使用子变量而不重写函数 Class
Use child variable without to rewrite function Class
我有一个问题是可以使用 children 变量来显示一些东西。
例如:
// Entity.hpp
class Entity {
public:
Entity();
~Entity();
// For this function
virtual void attack();
virtual int getNbAttack();
protected:
private:
int _nbAttack = 0;
int _nbAttackCost = 0;
std::string _msgAttack = "message class Entity";
};
// Player.hpp
class Player : public {
public:
Entity();
~Entity();
protected:
private:
int _nbAttack = 5;
int _nbAttackCost = 5;
std::string _msgAttack = "message class Player";
};
// Entity.cpp
int Entity::attack() {
this->_power -= 10;
std::cout << _msgAttack << std::endl;
return this->_nbAttack;
}
是否可以这样做:
// Main.cpp
Entity entity;
entity.attack();
std::cout << entity.getNbAttack() << std::endl;
Player player;
player.attack();
std::cout << player.getNbAttack() << std::endl;
结果:
message class Entity
0
message class Player
5
这可能吗,还是我必须重写我的函数?
在此先感谢您的帮助!
你绝对可以做到。
但是您需要对您发布的代码进行一些更改:
- 将
Entity
作为基础 class 添加到 Player
的 class 定义中(在 public
之后缺失)
- 保护
Entity
的数据成员或为它们添加受保护的 setter
- 如果您想在派生的 class 中使用基础 class' 构造函数,请使用
using Entity::Entity;
,但要声明 Player
的 constructors/destructor Player();
和 ~Player();
分别。
- 缺少成员变量声明(
power
)
- [可选] 您可以去掉
this->
以从 class 中访问成员。可以用,但不是绝对必要
一般来说,我有两个提示:
第一:试试吧。使用编译器和 运行 你的程序。您还可以使用 https://godbolt.org/ 之类的页面来 运行 您的代码(请注意,对于初学者来说,这些信息可能太多了)。
第二:找一本关于编程语言的好书and/or看https://en.cppreference.com/w/cpp
你可以这样做,但至少在我看来,这是一个相当糟糕的主意。
如果您想要两个在其他方面相似但存储不同固定值的 classes,我会使用模板:
#include <iostream>
// This is to represent a string literal, since we can't actually
// pass a string literal as a template argument.
template<size_t N>
struct string_literal {
char data[N];
constexpr string_literal(const char (&input)[N]) {
std::copy_n(input, N, data);
}
operator char const *() const { return data; }
};
template <int N, string_literal name>
class basic_entity {
public:
int attack() const {
std::cout << name << " attack ";
return nbAttack;
}
private:
int nbAttack = N;
};
int main() {
using Entity = basic_entity<0, "Entity">;
using Player = basic_entity<5, "PLayer">;
Entity entity;
Player player;
std::cout << entity.attack() << "\n";
std::cout << player.attack() << "\n";
}
这会产生如下结果:
Entity attack 0
PLayer attack 5
我可以看到两种值得考虑继承的情况。第一个是您使用的是较旧的编译器(string_literal
class 需要 C++20)。第二种情况是,如果您希望能够创建单个项目容器,其中每个项目可以是 Entity
或 Player
(或者更准确地说,是指向其中一个的指针)。然而,这也可以使用 std::variant<Entity, Player>
来实现,这可能是首选的替代方案(特别是,每个项目仍将“就地”分配,而不是需要指向单独分配的项目的指针容器)。
我有一个问题是可以使用 children 变量来显示一些东西。
例如:
// Entity.hpp
class Entity {
public:
Entity();
~Entity();
// For this function
virtual void attack();
virtual int getNbAttack();
protected:
private:
int _nbAttack = 0;
int _nbAttackCost = 0;
std::string _msgAttack = "message class Entity";
};
// Player.hpp
class Player : public {
public:
Entity();
~Entity();
protected:
private:
int _nbAttack = 5;
int _nbAttackCost = 5;
std::string _msgAttack = "message class Player";
};
// Entity.cpp
int Entity::attack() {
this->_power -= 10;
std::cout << _msgAttack << std::endl;
return this->_nbAttack;
}
是否可以这样做:
// Main.cpp
Entity entity;
entity.attack();
std::cout << entity.getNbAttack() << std::endl;
Player player;
player.attack();
std::cout << player.getNbAttack() << std::endl;
结果:
message class Entity
0
message class Player
5
这可能吗,还是我必须重写我的函数?
在此先感谢您的帮助!
你绝对可以做到。 但是您需要对您发布的代码进行一些更改:
- 将
Entity
作为基础 class 添加到Player
的 class 定义中(在public
之后缺失) - 保护
Entity
的数据成员或为它们添加受保护的 setter - 如果您想在派生的 class 中使用基础 class' 构造函数,请使用
using Entity::Entity;
,但要声明Player
的 constructors/destructorPlayer();
和~Player();
分别。 - 缺少成员变量声明(
power
) - [可选] 您可以去掉
this->
以从 class 中访问成员。可以用,但不是绝对必要
一般来说,我有两个提示:
第一:试试吧。使用编译器和 运行 你的程序。您还可以使用 https://godbolt.org/ 之类的页面来 运行 您的代码(请注意,对于初学者来说,这些信息可能太多了)。
第二:找一本关于编程语言的好书and/or看https://en.cppreference.com/w/cpp
你可以这样做,但至少在我看来,这是一个相当糟糕的主意。
如果您想要两个在其他方面相似但存储不同固定值的 classes,我会使用模板:
#include <iostream>
// This is to represent a string literal, since we can't actually
// pass a string literal as a template argument.
template<size_t N>
struct string_literal {
char data[N];
constexpr string_literal(const char (&input)[N]) {
std::copy_n(input, N, data);
}
operator char const *() const { return data; }
};
template <int N, string_literal name>
class basic_entity {
public:
int attack() const {
std::cout << name << " attack ";
return nbAttack;
}
private:
int nbAttack = N;
};
int main() {
using Entity = basic_entity<0, "Entity">;
using Player = basic_entity<5, "PLayer">;
Entity entity;
Player player;
std::cout << entity.attack() << "\n";
std::cout << player.attack() << "\n";
}
这会产生如下结果:
Entity attack 0
PLayer attack 5
我可以看到两种值得考虑继承的情况。第一个是您使用的是较旧的编译器(string_literal
class 需要 C++20)。第二种情况是,如果您希望能够创建单个项目容器,其中每个项目可以是 Entity
或 Player
(或者更准确地说,是指向其中一个的指针)。然而,这也可以使用 std::variant<Entity, Player>
来实现,这可能是首选的替代方案(特别是,每个项目仍将“就地”分配,而不是需要指向单独分配的项目的指针容器)。