Thread: Do you need to call Base class's Copy Constructor in a Derived class?

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    284

    Do you need to call Base class's Copy Constructor in a Derived class?

    Hi, folks,

    I am read the book <Efficient C++>. It says:
    When you implement your own Copy Constructor for a derived class, you need to explicitly call its Base Copy Constructor, otherwise the member in Base won't be copied. I really am confused why you can call a copy constructor directly .

    Look at the code below:
    Code:
    class A{
    public:
        int x;
        A():x(0){}
        A(const A& rhs){
            //x=rhs.x; //intentionally comment this out 
            cout<<"A::A(const A& rhs)"<<endl;
        }
        void check(){cout<<x<<endl;}
    };
    
    class B : public A{
    public:
        int y;
        B():y(0){}
        B(const B& rhs):A(rhs){
            y = rhs.y;
            cout<<"B::B(const B& rhs)"<<endl;
        };
    };
    
    class C : public A{
    public:
        int y;
        C():y(0){}
        C(const C& rhs){
            y = rhs.y;
            cout<<"C::C(const C& rhs)"<<endl;
        };
    };
    
    int main(){
        B obj1;
        obj1.x=1;
        B obj2(obj1);
        obj2.check();
        C obj3;
        obj3.x=1;
        C obj4(obj3);
       ojb4.check();
       return 0;
    }
    The result is:
    A::A(const A& rhs)
    B::B(const B& rhs)
    1073836148
    C::C(const C& rhs)
    0
    My questions are:

    1) When C's copy constructor is called, does it call C::A() to initialize x ?

    2). Can we call a Copy Constructor directly like this:
    Code:
    B(const B& rhs):A(rhs)
    ?
    Why
    Code:
    B(const B& rhs){
    A(rhs);
    }
    gets a complier error?


    Thanks!
    Last edited by meili100; 06-19-2008 at 09:57 PM.

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I guess the best way to prove to you that you should call a base copy constructor in a derived copy constructor is to demonstrate that when you don't need to write your own for the derived class, the compiler writes one that calls the base copy constructor.
    Code:
    #include <iostream>
    #include <ostream>
    
    class foo
    {
    public:
        foo (int d=0): _data(d)
        {
            std::cout<<"foo constructed\n";
        }
    
        foo (const foo &rhs): _data(rhs._data)
        {
            std::cout<<"foo(const foo &rhs) called\n";
        }
    protected:
        int _data;
    };
    
    class bar: public foo 
    {
    public:
        explicit bar (int dd): foo(dd)
        {
            std::cout<<"bar constructed\n";
        }
    };
    
    int main ()
    {
        bar b(-1);
        bar c(b);
    }
    foo constructed
    bar constructed
    foo(const foo &rhs) called

    It's no different for when your copy constructors would do special work.

    As far as your problem with C::A::x goes, I think it's because you commented out the assignment for that variable. Incidentally, be aware that copy constructors /are/ constructors and should use initializer lists if possible.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    Thanks, but why the following is error?

    Code:
    class bar: public foo 
    {
    public:
        explicit bar (int dd)
        {
            foo(dd);
            std::cout<<"bar constructed\n";
        }
    };

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Invoking the base class constructor is done in the initialisation list, not the constructor body.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    Thanks! I never heard of that.

    Quote Originally Posted by laserlight View Post
    Invoking the base class constructor is done in the initialisation list, not the constructor body.

  6. #6
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    I guess only a Copy Constructor can invoke a base class constructor (in the initialisation list). Is that right?

    Quote Originally Posted by laserlight View Post
    Invoking the base class constructor is done in the initialisation list, not the constructor body.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    >> I guess only a Copy Constructor can invoke a base class constructor

    Not necessarily - if you wanted to build new, unrelated objects out of copies of other objects that is acceptable also. You do it all the time when you use initializer lists.

  8. #8
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    No, I mean a constructor can not call a construct or in its initialization list.
    Am I right?

    Code:
    B():A(); //wrong?
    Quote Originally Posted by citizen View Post
    >> I guess only a Copy Constructor can invoke a base class constructor

    Not necessarily - if you wanted to build new, unrelated objects out of copies of other objects that is acceptable also. You do it all the time when you use initializer lists.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Any derived class constructor can invoke any non-private base class constructor from its initialisation list. Consequently, if B is derived from A, and A's default constructor exists and is non-private, it is correct to write:
    Code:
    B() : A() {}
    However, since the default constructor of the base class is called automatically, the use of the initialisation list would be redundant in this case.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    However, it's perfectly possible and useful to call constructors taking different arguments in the initialization list.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Virtual base class
    By George2 in forum C++ Programming
    Replies: 7
    Last Post: 03-14-2008, 07:45 AM
  2. Help calling function is asm
    By brietje698 in forum C++ Programming
    Replies: 24
    Last Post: 12-06-2007, 04:48 PM
  3. Replies: 18
    Last Post: 11-21-2007, 10:38 AM
  4. Two conceptual questions
    By AntiScience in forum C++ Programming
    Replies: 3
    Last Post: 11-01-2007, 11:36 AM
  5. Replies: 1
    Last Post: 11-27-2001, 01:07 PM