![](/img/trans.png)
[英]Inherited member from an abstract class can't be initialized by the inherited constructor
[英]Can't access inherited members of class in constructor
我是C ++的新手。 我有簡單的Unit類和hero類,它們是從Unit類繼承的。 Hero類有2個附加參數,但構造函數無法達到父級的類參數。 這是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
這是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;
};
這是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
最后,這是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;
}
這是控制台輸出:
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)
^
問題出在哪兒? 對不起,英語不好。 我希望我問的問題對,為我帶來了許多新名詞。 先感謝您。
您的基類應負責通常通過構造函數方法初始化其變量。
這個:
unsigned short max_health = 100;
string name = "Dummy";
short health = 100;
short damage = 10;
bool isDead = 0;
看起來不潔。 這些成員應在構造函數中初始化:
Unit::Unit()
: max_health(100),
name("Dummy"),
health(100),
damage(10),
isDead(false)
{ ; }
另外,對於bool
變量,應使用true
或false
,而不是數字。
編輯1:重復的成員名稱
您的子類應避免與基類具有相同的變量名。
Hero中的行:
string name;
遮蔽或隱藏基類成員:
string name;
如果您希望遵守此約定,則應使用范圍解析運算符 ::
來告訴編譯器您是指哪個成員:
Hero::name = "Hercules"; // Assign member in Hero class
Unit::name = "Person"; // Assign to member in Unit class.
在Unit的構造函數中初始化Unit的成員(如果只希望從Hero調用它,則可以是受保護的成員),並在Hero中初始化Hero的成員。 這就是初始化列表的工作方式。 或者,您可以在英雄的ctor括號之間初始化它們,但是不建議這樣做。
C ++不允許您從子類的初始化程序列表中初始化基類的成員。
做
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;
}
另外,您在單位和英雄中都有一個名為“名稱”的成員,您可能不想擺脫或重命名其中之一。
您要在Hero.cpp構造函數中嘗試做的是初始化基類的成員。 這聽起來很像基類本身的工作! 實際上,到了分號時,也就是說,基類構造函數Unit()已被調用(因此,它所包含的內容已經被初始化)。 因此,如果您要從Unit中刪除Unit(),則會出現編譯錯誤,因為另一個構造函數要帶參數。 而您必須像這樣明確指定:
Hero::Hero(string N, unsigned short HP, unsigned short MP, unsigned short AT):
Unit(HP, N, HP, AT),
max_mana(MP),
mana(MP),
{}
請注意,這一次,這里根本沒有調用Unit()-只是顯式調用了其他構造器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.