使用子变量而不重写函数 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)。第二种情况是,如果您希望能够创建单个项目容器,其中每个项目可以是 EntityPlayer(或者更准确地说,是指向其中一个的指针)。然而,这也可以使用 std::variant<Entity, Player> 来实现,这可能是首选的替代方案(特别是,每个项目仍将“就地”分配,而不是需要指向单独分配的项目的指针容器)。