1

Why does the default copy constructor not call the base constructor of monster but when I include a user-defined copy-constructor in troll it calls the parent (i.e.: monster) constructor?

As I think it works as follow: Create the base object and after that copy the elements inside.

Here is a sample code:

using std::cout;

struct monster {
    monster() {
        cout << "a monster is bread\n";
    }
    ~monster() {
        cout << "monster killed\n";
    }
    void health() {
        cout << "immortal?\n";
    }
    virtual void attack() {
        cout << "roar\n";
    }
};

struct troll: monster {
    troll() {
        cout << "a troll grows\n";
    }
    ~troll() {
        cout << "troll petrified\n";
    }
protected:
    int myhealth { 10 };
};

struct forum_troll: troll {
    forum_troll() :
            troll { } {
        cout << "not quite a monster\n";
    }
    ~forum_troll() {
        cout << "troll banned\n";
    }
};

int main() {
    cout << "a ------\n";
    forum_troll ft { };
    cout << "copy \n \n";
    troll t { ft };
    cout << "end \n \n";
}
JFMR
  • 23,265
  • 4
  • 52
  • 76
Charlie
  • 1,169
  • 2
  • 16
  • 31

1 Answers1

1

Why does the default copy constructor not call the Base Constructor but when I include a user-defined copy-constructor it calls the parent constructor?

What gets called is the copy constructor (not the default constructor) for the monster base class. The reason is that before the troll's default-generated copy constructor is called, the copy constructor of its base class (i.e.: monster) is called.

Paying attention to your code:

forum_troll ft { };
troll t { ft };

In the second statement, it is clear that troll's default-generated copy constructor (because you didn't provide any user-defined copy constructor) will be called. It is monster's copy constructor what is called (prior to troll's copy constructor), not its default constructor, because this is what the default-copy constructor does, i.e.: calling the base's copy constructor.

This default behaviour makes sense, since troll's base class is monster (a troll object is a monster object). Therefore, before copy constructing a troll, a monster has to be copy constructed.

When you provide a user-defined copy constructor for troll you are probably not explicitly calling monster's copy constructor and therefore monster default constructor is what gets called.

JFMR
  • 23,265
  • 4
  • 52
  • 76
  • yes, I didn't called the copy constructor of the Base class. As for clarification: The default copy constructor calls the base default copy constructor and so on? – Charlie Jan 26 '18 at 17:51
  • The *default-generated copy constructor* calls the base's copy constructor (regardless of whether that base's copy constructor is *default-generated* or *user-defined*). – JFMR Jan 26 '18 at 17:53
  • This means if I user define a copy constructor I should explicitly call the base's copy constructor and not the default constructor? – Charlie Jan 26 '18 at 17:57
  • Well, such an statement may be too broad. *Copy constructing* an object implies **constructing** the object and therefore the object's *base classes*. I recommend you to think about the **semantics of copying**. For example, in your code, you display *"a monster is bread"* by means of the default constructor as a sign of a `monster` being bred. However, doesn't copy constructing breed a `monster` ? Well, according to your code, it doesn't. Maybe it should be *"a monster is cloned"* for the copy constructor. Whatever makes sense for your application. – JFMR Jan 26 '18 at 18:05
  • BTW, I would strongly recommend you to read this as well: https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – JFMR Jan 26 '18 at 18:19
  • There were also some methods and properties like health I stripped out. – Charlie Jan 26 '18 at 18:30