Thread: Constructor inheritance

  1. #1
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879

    Constructor inheritance

    Just a quick question. Do copy constructors get inherited in derived classes?
    Code:
    class Animal
    {
    public:
       Animal(const Animal& orig) :age(orig.age) {}
    protected:
       int age;
    };
     
    class WoolyMammoth : public Animal
    {
    public:
       int blah();
    };
    Will WoolyMammoth have the same copy constructor as Animal, or would I need to define a new one?

    **EDIT**
    Actually, in this case is there even any need for a copy constructor, since the only data that's stored in the struct is an int?

    P.S. Someone's gotta fix these edit boxes... every time i hit 'edit', I lose all the indentation in my posted code. Very annoying.
    Last edited by Hunter2; 07-12-2004 at 04:49 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #2
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    That aside, constructors are not inherited. It doesn't make sense to inherit them, as the derived class is just that, a different class. With that said, you do have to construct the base class portion as well (which is done in your initializer list, and if not done explicitly, the default constructor is used). Here is a small example of how you might do a copy constructor:
    Code:
    class A
    {
    public:
       A(const A& obj) { ... }
    };
    
    class B : public A
    {
    public:
       B(const B& obj) : A(obj) { /* do stuff specific to the B class */ }
    };
    This copies the part of the object which is of type A through A's copy ctor, and then does whatever else it needs to make sure the part of it that is of type B explicitly in the function's enclosing braces.

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok, thanks. I was thinking about something along those lines, but wasn't sure if you could pass a B where an A was required. Silly me, I should have known (all those books and tutorials should have left an impression somewhere!). But while we're on the subject, do you generally need a copy constructor at all if the data in the class doesn't need special handling?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Well, remember that you aren't giving it an object of type B when it expects one of type A. Rather, you are giving it a reference to an object of type B which derives from A, so it all works out. As far as whether or not you need a copy constructor or not, that depends entirely on the class. If copying doesn't even make sense, then I declare the copy ctor and assignment operator as private members so that copying cannot be performed. If in some way it doesn't make sense, and the default behavior of a copy ctor will not work (for example, if there are pointers that need to have their values copied), then you should provide a copy ctor (and an assignment operator). Any time when copying makes sense, though, I make a habit of explicitly defining the copy ctor.

  5. #5
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    example, if there are pointers that need to have their values copied)
    I guess that's what got me to thinking about defining copy constructors - I'm used to everything needing special handling. My derived classes don't have any additional variables over the base, just different constructors and stuff like that (thread sync stuff - they all use HANDLE's and need WaitForSingleObject(), and CloseHandle works for them all). Since I don't really want a new sync object to be created each time I do an assignment etc., I guess the default constructor will do

    Any time when copying makes sense, though, I make a habit of explicitly defining the copy ctor.
    Cool, me too. That's actually why I'm asking this question, heh, because I have a whole load of derived classes from the same base and I don't want to define copy constructors for all of them one by one.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #6
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Zach L.
    That aside, constructors are not inherited.
    Yes they are! (in a way)

    A class doesn't need an explicitly defined copy constructor to invoke its base class copy constructor.

    Consider the following class structure:
    Code:
     
    struct A
    {
    	A(){}
    	A(const A&) 
    	{
    		std::cout << "A\'s copy constructor.";
    	}
    	int a;
    };
    struct B:
    	public A
    {
    	B(){}
    	int b;
    };
    B has not an explicitly defined copy constructor (only one generated by the compiler) but when we do this:
    Code:
    B b1;
    B b2 = b1;
    We can see that A's copy constructor gets invoked.

    When you think about it, it makes sense, because B should not have to care whether A needs a copy constructor or not when inheriting.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  7. #7
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Yes they are! (in a way)
    Its not that they're inherited, they just don't go away when you derive a class.

    When you think about it, it makes sense, because B should not have to care whether A needs a copy constructor or not when inheriting.
    And that probably does a better job explaining my own example than I did to begin with.

  8. #8
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>Its not that they're inherited, they just don't go away when you derive a class.
    Um, so you mean the copy constructor isn't really B's, but the compiler-generated copy constructor will call A's copy constructor by default anyway?

    >>because B should not have to care whether A needs a copy constructor or not when inheriting.
    Explain that please? I thought B needs to care because it's an A itself... Of course, neither really cares because they're just strings of 1's and 0's in the end, but I don't really get your example.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #9
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Hunter2
    Um, so you mean the copy constructor isn't really B's, but the compiler-generated copy constructor will call A's copy constructor by default anyway?
    Yes!
    Quote Originally Posted by Hunter2
    Explain that please? I thought B needs to care because it's an A itself... Of course, neither really cares because they're just strings of 1's and 0's in the end, but I don't really get your example.
    Well, when I am inheriting from a class with a copy constructor defined, I might not be aware that it has one. If the class I'm defining doesn't have a copy constructor, C++ defines it for me and implements the appropiate behaviour (which is to call A's copy constructor).
    It has to do with abstraction and data-hiding. I don't have to know how an object or class works to use it.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  10. #10
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    I'd say that it is preferable to know what is going on with the class you have derived from. Perhaps the copy works like that, but there is also the possibility that copying has been disabled (making the copy ctor and assignment operator private, for example). It's not data hiding. You want to know what the behavior is, and don't want that hidden.

Popular pages Recent additions subscribe to a feed