c++ - 继承和转换

标签 c++ inheritance

我正在编写一款 2d 游戏,希望从一开始就做好。我不太确定如何解决多重继承和强制转换。

例如,假设我有一个游戏世界。我创建了一个名为 Environment 的类,所有对象都将继承该类。

现在,如果我创建另一个名为 Brick 和 Ground 的类,这两个类将从环境中继承功能。现在假设我希望能够在接触 Brick 时爆炸,但地面类永远不会使用它,因此在环境类中创建一个类似的函数并使其成为虚拟的是一种浪费。

所以我虽然,也许如果我将环境对象转换回派生类并从那里调用它的函数:(下面只有一个例子来演示虽然过程)

#include <iostream>
#include <string>
#include <vector>
#include <limits>

class Environment
{
protected:
    std::string name;
    int health;
    int damage;
public:
    Environment(std::string _name)
    {
        this->name = _name;
    }

    virtual std::string GetType() = 0;

    std::string GetName()
    {
        return this->name;
    }

    void Spawn()
    {
        std::cout << this->name << ": Spawning object..." << std::endl;
    }

    int GetHealth()
    {
        return this->health;
    }

    void TakeDamage(int _damage)
    {
        this->health-=_damage;
    }

    virtual void Update() = 0;
    virtual void Render() = 0;
    virtual ~Environment(){}
};

class Ground : public Environment
{
private:

public:
    Ground(std::string _name) : Environment(_name)
    {

    }

    std::string GetType()
    {
        return "Ground";
    }

    void Update()
    {
        std::cout << "Updating: " << this->name << std::endl;
    }

    void Render()
    {

    }

};

class Brick : public Environment
{
private:

public:
    Brick(std::string _name) : Environment(_name)
    {
        this->name = "Brick Ansikte";
        this->health = 100;
    }

    std::string GetType()
    {
        return "Brick";
    }

    void Update()
    {
        std::cout << "Updating: " << this->name << std::endl;
    }

    void Render()
    {

    }

    void Explode()
    {
        std::cout << "Exploding BRICK" << std::endl;
    }
};

int main()
{
    std::vector<Environment*> listEnvironment;
    listEnvironment.push_back(new Ground("Ground fool"));
    listEnvironment.push_back(new Brick("Ground tun"));

    for(auto& env : listEnvironment)
    {
        std::cout << "HP: " << env->GetHealth() << std::endl; 
        env->Spawn();
        env->Update();
        if (env->GetType() == "Brick")
        {
            std::cout << "BRICK TYPE WAS FOUND, DYNAMIC CAST" << std::endl;
            static_cast<Brick*>(env)->Explode();

        }

        delete env;
    }
    listEnvironment.empty();


    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
    return 0;
}

这个解决方案是好是坏?或者我应该创建另一个基本助手类来保存游戏中可能发生的所有不同类型的 Action 吗?比如爆炸、反弹等等?

最好的问候 尼洛

最佳答案

有两种解决方法:

  1. 使用dynamic_cast:

    if (Brick* brick = dynamic_cast<Brick*>(env))
    {
        std::cout << "BRICK TYPE WAS FOUND, DYNAMIC CAST" << std::endl;
        brick->explode();
    }
    
  2. 将另一个方法添加到 Environment 中,命名为 MaybeExplode(这实际上是一个非常糟糕的名字,但我真的想不出更好的名字):

    virtual void MaybeExplode() {}
    

    现在,在 Brick 中覆盖它:

    void MaybeExplode()
    {
        std::cout << "Exploding BRICK" << std::endl;
    }
    

    然后在 for 循环中无条件地调用 MaybeExplode:

    ...
    env->Spawn();
    env->Update();
    env->MaybeExplode();
    
    delete env;
    

    不是浪费。这确实是 OO 设计的方式。要求爆炸的人不知道 什么 env 是什么。

    此外,dynamic_cast 实际上是 slower than a virtual function ,所以,如果有的话,你当前的版本是更多浪费。

关于c++ - 继承和转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29951502/

相关文章:

c# - 从嵌套类访问外部类隐藏基属性

C++:C 结构的继承或类成员?

java - 当子类对象传递给带有父类(super class)参数的方法时会发生什么?

c++ - 在函数调用中从 %esp 中减去分配了多少空间?

C++ 类对象作为函数参数

python - Pycharm 警告 : must implement all abstract methods

c++ - C++对析构函数的 undefined reference 和对返回的局部变量的引用

c++ - 获取垃圾文本。如何将字符数组变量转换为 LPARAM 类型?

C++ fstream 错误

c++ - 为什么在复制对象时忽略顶级常量?