Reputation:
I wasn't sure how to word what I'm looking for, which is probably why I can't find an answer by searching. Basically, I've got a class with another object as a member, and I want to initialize that member as an instance that is a subclass of that members type. The encapsulating class is called Game, and the member variable is of classtype GameState, and I would like to initialize it as a new instance of MainMenuGameState, which extends 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();
}
I can think of how to do this in Java, but not in C++. Thanks!
Upvotes: 0
Views: 2115
Reputation: 11028
Use a pointer to the base class: GameState* pGameState
.
And then in your constructor:
MainMenuGameState::MainMenuGameState() :
pGameState(new MainMenuGameState())
{
}
MainMenuGameState::~MainMenuGameState()
{
delete pGameState;
}
And you should add a virtual destructor to GameState so it can properly clean up any resources:
class GameState {
public:
virtual ~GameState() {}
}
Upvotes: 0
Reputation: 69864
One of the many fundamental language differences between Java and C++ is that all Java objects are implicitly referenced through shared pointers.
C++ gives you the choice (and therefore the burden) of expressing whether objects should be managed by the scope of pointers to them, or by the scope of the object itself.
In order to hold any polymorphic object you must hold it through some means of pointer (as the the other answers mention, best to use unique_ptr or shared_ptr depending on whether the object's lifetime is to be managed by one owner or many).
full example (warnings fixed):
#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;
}
Upvotes: 4
Reputation: 96810
Use a pointer, preferably std::unique_ptr
:
#include <memory>
class Game {
private:
std::unique_ptr<GameState> gameState;
public:
Game()
: gameState(std::unique<MainMenuGameState>(new MainMenuGameState())) { }
};
Upvotes: 1