I have a Triangle class which has members

Point P1, P2, P3;

So generally I pass the constructor 3 points.

Point A(1,1,1);
Point B(1,1,0);
Point C(0,0,1);
Triangle T(A,B,C);

Then I have a bunch of functions that I can pass point's to such as to find intersections and distances etc.

However, now I would like to make a triangle which stores pointers to points, so that when I change the positions of the points, the triangle is automatically updated.

Ie.

Point A(1,1,1);
Point B(1,1,0);
Point C(0,0,1);
Triangle(&A, &B, &C);

This way when I do

A.setX(3);

The triangle now thinks the points (3,1,1), (1,1,0), (0,0,1) are its three points.

Is there some way to do this dual functionality in one class? Or do I need to make a ValueTriangle and a PointerTriangle class?

Thanks,

Dave

Dani AI

Generated

asked whether a single Triangle class can handle both owning (value) points and non-owning/pointer semantics. correctly hinted at several low-level options. A practical, modern approach is to pick one clear internal representation and offer constructors that create the right representation for callers — that keeps semantics explicit and avoids unsafe surprises.

One convenient single-class strategy is to store std::shared_ptr<Point> internally and provide two constructor sets: one that accepts const Point& and copies into new shared_ptrs, and one that accepts std::shared_ptr<Point> to reference externally owned points. Accessors always dereference the shared_ptr, so the triangle "sees" updates when the same shared object is modified:

class Triangle {
    std::shared_ptr<Point> a_, b_, c_;
public:
    Triangle(const Point& a, const Point& b, const Point& c)
      : a_(std::make_shared<Point>(a)), b_(std::make_shared<Point>(b)), c_(std::make_shared<Point>(c)) {}

    Triangle(std::shared_ptr<Point> a, std::shared_ptr<Point> b, std::shared_ptr<Point> c)
      : a_(std::move(a)), b_(std::move(b)), c_(std::move(c)) {}

    Point& A() { return *a_; }
    const Point& A() const { return *a_; }
    // ...
};

For a lightweight non-owning alternative, use std::reference_wrapper<Point> so no heap allocation is required — but document that the caller must guarantee the referenced Points outlive the Triangle:

class TriangleRef {
    std::reference_wrapper<Point> a_, b_, c_;
public:
    TriangleRef(std::reference_wrapper<Point> a,
                std::reference_wrapper<Point> b,
                std::reference_wrapper<Point> c)
      : a_(a), b_(b), c_(c) {}
    Point& A() { return a_.get(); }
};

A hybrid "proxy" (PointHandle) can encapsulate either an owned shared_ptr or a non-owning raw/reference pointer and expose a uniform get(); that implements 's proxy idea concretely. Key cautions: never wrap stack objects in owning smart pointers, clearly document ownership semantics, and prefer value storage for small immutable Point types unless shared mutability is required.

The classic solution is a union, but you can't have a union of points unless the Point class has a trivial constructor.

Another option is to store objects of a proxy class instead of storing Point objects directly. The proxy class will handle the disconnect between objects and pointers, and your Triangle class can largely ignore it.

You can also make your Triangle class a template class and then have a pointer specialization, but that's really just a cute way of having two separate classes in this case. ;)

commented: I like option #2 =) +4
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.