我不确定如何说出我正在寻找的内容,这可能就是我无法通过搜索找到答案的原因。基本上,我有一个带有另一个对象作为成员的类,我想将该成员初始化为一个实例,该实例是该成员类型的子类。封装类称为Game,成员变量是classtype GameState,我想将它初始化为MainMenuGameState的新实例,它扩展了GameState。
class MainMenuGameState : public GameState {
public:
MainMenuGameState();
};
class GameState {}; //Will be abstract class, not to be instantiated
class Game {
private:
GameState gameState; //Would want this to be initialized as a MainMenuGameState, not just a GameState;
public:
Game();
}
我可以想到如何在Java中实现这一点,但在C ++中却没有。谢谢!
答案 0 :(得分:4)
Java和C ++之间的许多基本语言差异之一是所有Java对象都是通过共享指针隐式引用的。
C ++为您提供了表达是否应该通过指针范围或对象本身范围来管理对象的选择(因而也是负担)。
为了保存任何多态对象,你必须通过某种指针来保持它(正如其他答案所提到的,最好使用unique_ptr或shared_ptr,具体取决于对象的生命周期是由一个所有者还是多个人管理)。
完整示例(警告已修复):
#include <memory>
class GameState {
public:
virtual ~GameState() = default;
}; //Will be abstract class, not to be instantiated
class MainMenuGameState
: public GameState
{
public:
MainMenuGameState() {}
};
class Game {
private:
std::unique_ptr<GameState> gameState; //Would want this to be initialized as a MainMenuGameState, not just a GameState;
public:
Game();
};
Game::Game()
: gameState { new MainMenuGameState }
{}
using namespace std;
int main()
{
Game g;
return 0;
}
答案 1 :(得分:1)
使用指向基类的指针:GameState* pGameState
。
然后在你的构造函数中:
MainMenuGameState::MainMenuGameState() :
pGameState(new MainMenuGameState())
{
}
MainMenuGameState::~MainMenuGameState()
{
delete pGameState;
}
你应该向GameState添加一个虚拟析构函数,以便它可以正确地清理任何资源:
class GameState {
public:
virtual ~GameState() {}
}
答案 2 :(得分:1)
使用指针,最好是std::unique_ptr
:
#include <memory>
class Game {
private:
std::unique_ptr<GameState> gameState;
public:
Game()
: gameState(std::unique<MainMenuGameState>(new MainMenuGameState())) { }
};