0

I'm working through this course on udemy and I'm baffled at this output.

The default parent constructor for Creature() is called even when I call the constructor through the child's constructor. I've been in JavaScript land the last 8 years so I've seen some wacky stuff, but I'm not sure how I'm accident pull this off.

P.S. I know this isnt pretty code, its for the course.

#include <iostream>;
#include <string>;

using namespace std;

class Creature
{
public:
    Creature();
    Creature(string name, float health);

    string Name;
    float Health;
};

class Dragon:public Creature
{
public:
    Dragon();
    Dragon(string name, float health);
};

int main()
{
    Dragon dragon2("Smaug", 100.f);
    cout << "The Dragon's name should be Smaug: " << dragon2.Name << endl;
    
    return 0;
}
 
Creature::Creature(string name, float health)
{
    Name = name;
    Health = health;
    cout << "Creature constructor WITH arguments" << endl;
};

Creature::Creature() 
    : Name("UNAMED"), Health(100.f)
{
    cout << "Creature constructor with NO arguments" << endl;
}

Dragon::Dragon(string name, float health)
{
    Creature(name, health);
    cout << "Dragon constructor WITH arguments" << endl;
}

Dragon::Dragon()
{
    cout << "Dragon Constructor with NO arguments" << endl;
}

Output:

Creature constructor with NO arguments
Creature constructor WITH arguments
Dragon constructor WITH arguments
The Dragon's name should be Smaug: UNAMED

I understand (sorta) why and how default constructors would be called, but I expected the output to be:

Creature constructor WITH arguments
Dragon constructor WITH arguments
The Dragon's name should be Smaug: Smaug
JDillon522
  • 19,046
  • 15
  • 47
  • 81
  • 2
    Your parametrized Dragon constructor should be calling the Creature constructor from the member initialization list, not the body of the constructor. – Nathan Pierson Sep 18 '21 at 23:12
  • Also this doesn't actually have anything to do with multiple inheritance. Multiple inheritance refers to a single class inheriting from multiple different base classes, which `Dragon` does not do. – Nathan Pierson Sep 18 '21 at 23:34

1 Answers1

4

This is wrong:

Dragon::Dragon(string name, float health)
{
    Creature(name, health);
    cout << "Dragon constructor WITH arguments" << endl;
}

Well, it is syntactically correct but it is not doing what you think it does. Creature(name,health); calls the constructor of Creature to create a temporary that lives till the end of that line. You see the default constructor getting called because you do not call the Creature constructor for the Dragon that is being constructed, hence the Creature part of the Dragon is default constructed.

To call the base constructor:

class Dragon : public Creature
{
public:
    Dragon();
    Dragon(string name, float health) : Creature(name,health) {
        cout << "Dragon constructor WITH arguments" << endl;
    }
};
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • Yup. True story: If I had just watched the next video in the course he went over this same point. – JDillon522 Sep 18 '21 at 23:16
  • 2
    @JDillon522 I don't think it is possible to learn C++ by watching videos. I don't want to exclude the possibility that there is a good video tutorial, though it would not teach you `using namespace std;` (rather explain [why to avoid it](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)). I recommend to use a [book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) instead. – 463035818_is_not_an_ai Sep 18 '21 at 23:21