Alzurana
Alzurana

Reputation: 23

How do I call parent class copy constructors?

I came across a little problem with the inheritance of copy constructors. Copy constructors of parent classes are not called when I try to copy a class. Here is an example program which sums up the problem:

#include <iostream>

//parent class
class cParent
{
    public:
        //parent data
        int iParentData;
        //default constructor
        cParent(void) : iParentData(0) {}
        //copy constructor
        cParent(const cParent& SOURCE) : iParentData(SOURCE.iParentData) {}
};

//child class
class cChild : public cParent
{
    public:
        //child data
        int iChildData;
        //default constructor
        cChild(void) : iChildData(0) {}
        //copy constructor
        cChild(const cChild& SOURCE) : iChildData(SOURCE.iChildData) {}
};

int main()
{
    cChild SourceClass;             //create a class
    SourceClass.iParentData = 10;   //and set some values
    SourceClass.iChildData  = 10;   //
    cChild CopyClass(SourceClass);  //use the copy constructor
    std::cout << "Parent Data: " << CopyClass.iParentData << std::endl; //magic, this is 0
    std::cout << "Child  Data: " << CopyClass.iChildData  << std::endl; //and this is 10
    return 0;
}

Output:

Parent Data: 0
Child  Data: 10

So obviously, the copy constructor of the child class is called, but the parent class calls the default constructor. Is there any way for force the call of parent class copy constructors within child class copy constructors?

Thanks in advance for your help :)

*EDIT:

For everyone who wants to know, the solution is simple:

//copy constructor
cChild(const cChild& SOURCE) : cParent(SOURCE), iChildData(SOURCE.iChildData) {}

This pretty much fixes the whole problem by calling the parents copy constructor

Thanks to everyone for the fast replies!

Upvotes: 1

Views: 6643

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311156

If you will not call the parent copy constructor explicitly when the compiler simply will initialize data member objects of the derived class using default constructors. So you have to write

cChild(const cChild& SOURCE) : cParent( SOURCE ), iChildData(SOURCE.iChildData) {}

See more detailed my description of the situation

Though it is written in Russian you can translate it into Englich using for example google service translator.

Upvotes: -2

Edward
Edward

Reputation: 304

Here is example:

struct Parent
{
    Parent()
    {
        std::cout << "Parent::Parent()\n";
    }

    Parent(const Parent&)
    {
        std::cout << "Parent::Parent(const Parent&)\n";
    }
};

struct Child: public Parent
{
    Child()
    {
        std::cout << "Child::Child()\n";
    }

    Child(const Child& c)
        : Parent(c)
    {
        std::cout << "Child::Child(const Child&)\n";
    }
};


int main()
{
    Child c1;
    Child c(c1);
}

Output you should get:

Parent::Parent()
Child::Child()
Parent::Parent(const Parent&)
Child::Child(const Child&)

Upvotes: 0

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145457

cChild(const cChild& other ) : cParent( other ), iChildData( other.iChildData) {}

You implicitly called the cParent default constructor.


By the way, about the notation:

  • Better reserve ALL UPPERCASE for macro symbols and those only. That way you avoid shouting in the ears of readers, and you reduce the chance of inadvertent text substitution.

  • Hungarian prefix notation is also best avoided. In particular prefixing class names with c only makes the code less readable. Microsoft do that because they generally employ all kinds of worst practices (void main etc.), but we can do better!

  • Writing (void) to indicate no arguments is a C-ism, unnecessary verbosity in C++.

Upvotes: 6

Related Questions