Ale
Ale

Reputation: 1199

Copy constructor and composition

I have a relationship of composition between class A and B,

class A
{
    A(); //default constructor  //EDIT
    A(const A &mA); // copy constructor //EDIT
    virtual ~A();
};


class B
{
B(A *pA); //constructor
B(const B &mB) //copy constructor
virtual ~B(); //EDIT: destructor to eliminate mA and to build the composition
A* mA;
};

Could I write the copy constructor in this manner:

B(const B &mB, A *pA)

I need it to keep up the composition also between the copied objects. Is it wrong? Does it exist a better solution? Thank you

EDIT: I'll try to explain me better. I want a copy of the object mB and the object mA. But if in the copy constructor I had writen mA =mB.mA I would copy the adress to the original object mA. So I think I need a deep copy not an swallow copy. My confusion arise because now, from the main, first I copy the object mA and then I copy mB. Doing that, I think I need to assign the copied object mA with an external function like

foo(A *pA)

Otherwise I could solve the problem if I could doing a deep copy of mB. Is this called a deep copy?

P.S. A and B are abstract classes

Upvotes: 2

Views: 1627

Answers (2)

Kerrek SB
Kerrek SB

Reputation: 477436

You might be overthinking this. The copy constructor simply needs to initialize all members to the corresponding values of the source object, e.g. like so:

B(B const & rhs) : mA(rhs.mA) { }

This is just the trivial copy, though, so if there's nothing else to it, then you'd better not write any copy constructor at all.

On the other hand, if you want a deep copy, it could be something like this:

B(B const & rhs) : mA(::new A(rhs.mA)) { }

However, the details of that depend on the actual ownership policy of class B with regard to the pointee mA. Depending on those details, don't forget to write an appropriate destructor, if necessary.

You should also write a matching assignment operator of your copy constructor does something non-trivial, for example:

B & operator=(B const & rhs)
{
    if (this != &rhs)
    {
        A * tmp = ::new A(*rhs.mA);    // need try/catch in general!
        ::delete mA; // OK, no exception occurred if we got here
        mA = tmp;
    }
    return *this;
}

Upvotes: 0

David Grayson
David Grayson

Reputation: 87486

No. By definition, the copy constructor can not have a signature like the one you described. Here are some valid signatures for copy constructors:

B(const B &);
B(B &);   // Thanks Oli!

Why do you need it? You can access the mA member inside the copy constructor by doing something like this (I might have made some syntax errors):

B::B(const B & original)
{
    mA = original.mA;
}

Upvotes: 6

Related Questions