Reputation: 111
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.
Upvotes: 0
Views: 1771
Reputation: 1693
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 want to get rid of, or rename, one of them.
Upvotes: 1
Reputation: 1665
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.
Upvotes: 0
Reputation: 57749
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.
Upvotes: 3
Reputation: 10880
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.
Upvotes: 0