【问题标题】:C++ Polymorphism and OverridingC++ 多态性和覆盖
【发布时间】:2012-10-11 04:56:56
【问题描述】:

我很难让它在 C++ 中工作,我已经在 C# 中管理它,但我没有经常使用 C++,所以我不确定语法。

这样做的目的是为了一个简单的状态管理器,每个状态都继承自一个名为“状态”的基类。

我已经开始工作,但我似乎无法管理多态性方面。那就是我不能有一个对象“State currentState”并将该对象设置为等于“menuState”并让它运行所需的功能,我知道这是因为它只是找到State类的签名,但我不确定如何躲开它。这是一些简化的代码,以便有人可以帮助我理解。

// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

// State.h
class State{
public:
  virtual void drawState();
};

// State.cpp
void State::drawState() {
    cout << "Base state.\n";
}

// MenuState.h
class MenuState: public State {
public:
  virtual void drawState();
};


// MenuState.cpp
void MenuState::drawState() {
    cout << "Menu state.\n";
    State::drawState();
}

int main ()
{
    State currentState;
    MenuState menuState;

    currentState = menuState;
    currentState.drawState();

    system("pause");
    return 0;
}

如果您更改“State currentState”以创建 MenuState 的对象,则代码将按我的要求工作,但是我需要它作为父类,以便我可以将当​​前状态设置为我将在其中创建的其他状态GameState 等未来。

谢谢。

【问题讨论】:

    标签: c++ inheritance polymorphism overriding


    【解决方案1】:

    由于切片,多态性不适用于普通对象。您必须使用引用或(智能)指针。在您的情况下,不能重新分配作为引用的指针:

    int main ()
    {
        State* currentState = NULL;
        MenuState menuState;
    
        currentState = &menuState;
        currentState->drawState(); //calls MenuState::drawState()
    
        NextState nextState; //fictional class
        currentState = &nextState;
        currentState->drawState(); //calls NextState::drawState()
    
        system("pause");
        return 0;
    }
    

    在您的代码中:

    State currentState;
    MenuState menuState;
    
    currentState = menuState;
    

    分配切片menuState - 它基本上只是将其中的State 部分复制到currentState,丢失所有其他类型信息。

    【讨论】:

    • 是的,C++ 与 C# 的不同之处在于,默认情况下 C# 用户定义的类型都是“引用类型”。将 Foo myFoo; 从 C# 转换为 C++ 会产生类似 Foo *myFoo = new Foo; 的结果(取决于 C# 中 Foo 的实际定义,我理解 C# 添加了用户定义的值类型)。
    • 很有魅力!回复快,信息量大!感谢您的帮助。
    【解决方案2】:

    将您的代码更改为:

    int main ()
    {
        State *currentState;
    
        currentState = new MenuState();
        currentState->drawState();
    
        system("pause");
        delete(currentState)
        return 0;
    }
    

    【讨论】:

    • 不需要动态分配(应尽可能避免),此外,此代码会泄漏内存。
    • @LuchianGrigore 你这么说是因为这个OP的代码没有实现多态破坏(虚拟dtors)吗?如果是这样,那 deleter 而不是 OP 的类的错是什么? (并且首先为完全不必要的动态分配 +1)。
    • @WhozCraig 我评论的第二部分不再适用(最初,答案没有delete currentState)。现在,它只会导致未定义的行为(由于您所说的原因)。
    • @LuchianGrigore 好的。因为我没有看到编辑历史记录(该死的 safari 又一次把我拉来扯去)。
    • 啊,我应该在我的答案中添加一个关于编辑的注释。抱歉 - 我根据 @LuchianGrigore 的内存泄漏说明对其进行了编辑。这次讨论教会了我一些我不知道的关于 C++ 的事情,非常感谢 =)
    猜你喜欢
    • 2012-02-08
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    相关资源
    最近更新 更多