1

I have a class where in a specific case some of its attributes need to reference an external variable. I managed to do in this way, but is there a better way?

#include "Vector.h"

class LineSeg
{
private:
    Vector* a;
    Vector* b;
    bool owns;
public:
    LineSeg(){
        a = new Vector();
        b = new Vector();
        owns = true;
    }
    LineSeg(Vector ap, Vector bp){
        a = new Vector(ap);
        b = new Vector(bp);
        owns = true;
    }
    LineSeg(Vector &ap, Vector &bp, bool owns){
        a = ≈
        b = &bp;
        owns = false;
    }
    virtual ~LineSeg(){
        if(owns){
            delete a;
            delete b;
        }
    }
};

I can't make two different classes.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • you should probably opt for either copy-always or liberal use of `shared_ptr` – kmdreko Jan 16 '18 at 06:27
  • 1
    There's an error in your 3rd constructor - a) your'e shadowing your `owns` member with your `owns` parameter, and b) your'e not using the parameter at all - you set it to `false` which has no effect – user2328447 Jan 16 '18 at 06:39

1 Answers1

1

When doing such things (happens occasionally especially for mutexes), I usually use pointer to members. This avoids any special treatment and delete in the destructor.

#include "Vector.h"

class LineSeg
{
private:
    Vector a0;
    Vector b0;
    Vector* a = &a0;
    Vector* b = &b0;
public:
    LineSeg()
    {
    }
    LineSeg(Vector &ap, Vector &bp, bool copy) {
        if( copy )
        {
            a0 = ap;
            b0 = bp;
            return;
        }
        a = ≈
        b = &bp;
    }
    virtual ~LineSeg(){
    }
};

However, this comes with some memory cost when external references are used, since a0 and b0 still use space in the class, though not used. However, such a construct is necessary rarely, and it's worth the little memory cost imo.

But design-wise this construct is questionnable, because it is potentially confusing and dangerous. Let's say you add a method clear(), which clears the both Vector members:

void clear() {
    a->clear();
    b->clear();
}

Now a colleague creates a LineSeg( myVector1, myVector2, false) and after some computing calls myLineSeg.clear() - that might be pretty confusing, because his own myVector1 and myVector2 are cleared.

That's why I limit this to special cases like mutexes, and usually only allow it protected.

Im most other cases vu1p3n0x is right - it's much better to use only one mechanism - either copy always, take ownership always, or use shared_ptr.

user2328447
  • 1,807
  • 1
  • 21
  • 27