C++ - Behaviour of derived class constructor

Viewed 48

I'm preparing my exam. Below is output of a sample question, the block 3 confuses me.

--- Block 1 ---
H
SM
2 x S
DP
--- Block 2 ---
H
SM
2 x S
DP
--- Block 3 ---
H
Copy SM
1 x S
Copy DP
--- Block 4 ---
H=
--- Block 5 ---
 ̃H
--- Block 6 ---
 ̃DP
 ̃S
 ̃SM
 ̃H
 ̃DP
 ̃S
 ̃SM
 ̃H

We pass a Deadpool type object to construct a new Deadpool object, so copy constructor(ctor) should be called. Deadpool copy ctor should call Spiderman copy ctor, because of inheritance. Then, Spiderman copy ctor calls Hero ctor for same reason, so why is there 1 x S? Who called the Sword constructor?

#include <iostream>
using namespace std;

class Weapon { };

class Sword : public Weapon {
public:
    Sword(int n = 1) { cout << n << " x S" << endl; }
    ~Sword() { cout << " ̃S" << endl; }
};

class Hero {
    Weapon* w;
public:
    Hero() { cout << "H" << endl; w = new Weapon; }
   ~Hero() { cout << " ̃H" << endl; delete w; }
    virtual const Hero& operator=(const Hero& h) { cout << "H=" << endl; return *this;}
};

class SpiderMan : public Hero {
    Weapon* w;
public:
    SpiderMan() { cout << "SM" << endl; w = new Weapon; }
    SpiderMan(const SpiderMan& s) { cout << "Copy SM" << endl; w = new Weapon; }
    virtual ~SpiderMan() { cout << " ̃SM" << endl; delete w; }
    const SpiderMan& operator=(const SpiderMan& s) { cout << "SM=" << endl; return *this;}
};

class DeadPool : public SpiderMan {
    Sword sword;
public:
    DeadPool() : sword(2) { cout << "DP" << endl; }
    DeadPool(const DeadPool& d) : SpiderMan(d) { cout << "Copy DP" << endl; }
    ~DeadPool() { cout << " ̃DP" << endl; }
    const DeadPool& operator=(const DeadPool& d) { cout << "DP=" << endl; return *this;}
};

int main() {
    cout << "--- Block 1 ---" << endl;
    Hero* hero = new DeadPool;
    cout << "--- Block 2 ---" << endl;
    SpiderMan* spiderman = new DeadPool;
    cout << "--- Block 3 ---" << endl;
    DeadPool deadpool(*dynamic_cast<DeadPool*>(spiderman));
    cout << "---        Block 4 ---" << endl;
    *hero = *spiderman;
    cout << "--- Block 5 ---" << endl;
    delete hero;
    cout << "--- Block 6 ---" << endl;
    delete spiderman;
}

1 Answers

Who called the Sword constructor?

DeadPool has a data member sword with type Sword, it's not mentioned in the copy constructor of DeadPool, then it'll be initialized by its default constructor. That's why you got the output 1 x S, between the invocation of the constructor of base SpiderMan and invocation of the constructor of DeadPool.

Related