简体   繁体   中英

Can't access inherited members of class in constructor

I am novice at C++. I have simple Unit class and hero Class, which is inherited of Unit class. Hero class have 2 additional parameters, but constructor can't reach parent's class parameters. Here is unit.hpp:

#ifndef UNIT_HPP
#define UNIT_HPP

#include <string>

using namespace std;

class Unit
{
public:
    unsigned short  max_health  = 100;
    string          name        = "Dummy";
    short           health      = 100;
    short           damage      = 10;
    bool            isDead      = 0;

    Unit();
    Unit(string, unsigned short, unsigned short);
};

#endif //UNIT_HPP

here is unit.cpp:

#include <string>
#include <iostream>

#include "unit.hpp"

using namespace std;

Unit::Unit()
{
    cout << "Dummy was created!" << endl;
};

Unit::Unit(string N, unsigned short HP, unsigned short AT):
    max_health(HP),
    name(N),
    health(HP),
    damage(AT)
{
    cout << N << " was created!" << endl;
};

Here is hero.hpp:

#ifndef HERO_HPP
#define HERO_HPP

#include <string>

#include "unit.hpp"

class Hero : public Unit
{
public:
    unsigned short  max_mana    = 100;
    string          name        = "The Brave Warrior";
    short           mana        = 100;

    Hero (string, unsigned short, unsigned short, unsigned short);

};

#endif //HERO_HPP

and finaly, here is hero.cpp:

#include <string>

#include "hero.hpp"

using namespace std;

Hero::Hero(string N, unsigned short HP, unsigned short MP, unsigned short AT):
    max_health(HP),
    max_mana(MP),
    name(N),
    health(HP),
    mana(MP),
    damage(AT)
{
    cout << "The Legendary Hero, " << N << ", was born!" << endl;
}

Here is console output:

src/hero.cpp: In constructor ‘Hero::Hero(std::__cxx11::string, short unsigned int, short unsigned int, short unsigned int)’:
src/hero.cpp:10:5: error: class ‘Hero’ does not have any field named ‘max_health’
     max_health(HP),
     ^
src/hero.cpp:13:5: error: class ‘Hero’ does not have any field named ‘health’
     health(HP),
     ^
src/hero.cpp:15:5: error: class ‘Hero’ does not have any field named ‘damage’
     damage(AT)
     ^

Where is the problem? Sorry for bad English. I hope I asked question right, so many new terms for me. Thank you in advance.

Your base class should be responsible for initializing its variables usually through a constructor method.

This:

unsigned short  max_health  = 100;
string          name        = "Dummy";
short           health      = 100;
short           damage      = 10;
bool            isDead      = 0;

does not look kosher. These members should be initialized in a constructor:

Unit::Unit()
: max_health(100),
name("Dummy"),
health(100),
damage(10),
isDead(false)
{ ; }

Also, with bool variables, you should use true or false , not numbers.

Edit 1: duplicate member names
Your child classes should avoid having the same variable names as the base class.

The line in Hero:

  string name;

shadows or hides the base class member:

  string name;

If you prefer to keep up this convention, you should use the scope resolution operator :: to tell the compiler which member you are referring to:

Hero::name = "Hercules"; // Assign member in Hero class
Unit::name = "Person";   // Assign to member in Unit class.   

Initialize Unit's members in Unit's constructor (possibly a protected one if you only would like it to be called from Hero), and Hero's members in Hero. That's how initializer lists work. Alternatively, you might init them inbetween the braces of Hero's ctor, but this is not recommended.

C++ doesn't allow you to initialize the base class' members from the subclass' initializer list.

Do

Hero::Hero(string N, unsigned short HP, unsigned short MP, unsigned short AT):
    Unit(N, HP, AT), // initializes the base class' members
    max_mana(MP),
    name(N),
    mana(MP),
{
    // but you could override the base class' members here
    isDead = true;
    cout << "The Legendary Hero, " << N << ", was zombified!" << endl;
}

Also, you have a member called 'name' in both Unit and Hero, you might not want to get rid of, or rename, one of them.

What you are trying to do in Hero.cpp constructor is to initialize members of the base class. Which sounds an awful lot like the job for the base class itself! In fact, by the time the semicolon is reached, so to say, the base class constructor Unit() has already been called (and, hence, what it contains was already initialized). So, if you were to remove Unit() from Unit, you would get a compilation error, because the other constructor has arguments to take. And those you would have to specify explicitly like this:

Hero::Hero(string N, unsigned short HP, unsigned short MP, unsigned short AT):
    Unit(HP, N, HP, AT),
    max_mana(MP),
    mana(MP),
    {}

Note that this time, Unit() is not called here at all - only the other contsructor is - explicitly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM