c++如何知道在状态模式中向何处转发声明
c++ how to know where to forward declare in state pattern
这个问题来自这个问题。我试图实现一个shared_ptr到容器(游戏)的状态模式。
然而,我有一个循环包含的问题,需要向前声明。
我代码:Game.h
#pragma once
#include <memory>
#include "BaseState.h"
class Game : public std::enable_shared_from_this<Game>
{
private:
std::shared_ptr<BaseState> currentState;
public:
Game();
void switchState(std::shared_ptr<BaseState> nextState);
void doSomething(char);
void runState();
};
cpp
#include "stdafx.h"
#include <iostream>
#include "Game.h"
#include "SomeState.h"
Game::Game()
{
currentState = std::make_shared<SomeState>();
}
void Game::switchState(std::shared_ptr<BaseState> nextState)
{
currentState = nextState;
}
void Game::doSomething(char c)
{
std::cout << "Game : " << c;
}
void Game::runState()
{
currentState->handleCommand(shared_from_this());
}
BaseState.h
#pragma once
#include <memory>
#include "Game.h"
class BaseState
{
public:
virtual void handleCommand(std::shared_ptr<Game>) = 0;
};
SomeState.h
#pragma once
#include "BaseState.h"
class SomeState :
public BaseState
{
public:
// Inherited via BaseState
virtual void handleCommand(std::shared_ptr<Game>) override;
};
cpp
#include "stdafx.h"
#include "SomeState.h"
void SomeState::handleCommand(std::shared_ptr<Game> game)
{
game->doSomething('S');
}
我读了其他关于前向声明的问题,但仍然不明白。
What I try;
forward declare BaseState in Game,代码编译但抛出错误。
ConsoleApplication1.exe中0x73E9DAE8的未处理异常:Microsoft c++异常:std::bad_weak_ptr在内存位置0 x00bbf5d4。
正向声明Game在BaseState中。Dosnt compile给出了未定义类型错误的使用,也是
'doSomething':不属于"std::要查看"
这是合乎逻辑的因为在编译时game没有doSomething函数因为forward声明像;
class Game;
我如何决定在哪里转发声明另一个类,是否有任何逻辑步骤,或者我应该选择一个并解决选择产生的问题?
您不需要在BaseState.h
中添加#include <Game.h>
,您可以简单地向前声明它
class Game;
这样做是因为BaseState
声明不需要知道Game
的内容。所以你先尝试的是可以的。Game.h
中的#include <BaseState.h>
也是如此。将其替换为BaseState
的前向声明。
std::bad_weak_ptr
异常是由其他原因引起的。具体来说,您可能错过了关于shared_from_this
的小细节,它表示
只允许在先前共享的对象上调用shared_from_this对象,即在由std::shared_ptr管理的对象上。否则,行为未定义
和
(来自c++ 17) std::bad_weak_ptr被抛出weak_this)的Shared_ptr构造函数
通常可以通过将对象实例化为shared_ptr
:
int main() {
auto myGame = std::make_shared<Game>();
. . .
myGame->runState();
. . .
}
编辑
请记住,使用shared_ptr
有一定的成本。一般来说,如果您知道指向对象总是比使用它的函数调用更长寿,就像您的BaseState::handleCommand
的情况一样,那么通过引用传递它可能会更快(并且仍然安全)。
- 正在折叠转发引用
- 将函数参数完美转发到函数指针:按值传递呢?
- 转发变量参数列表以模拟 std::thread
- 变量如何以及在何处可能没有C++关联的名称?
- 在按值调用 (c++) 中转发构造函数参数
- 存储稍后要转发的变量参数
- 如何在 C++ 中转发声明 std::set?
- C++使用默认模板参数键入别名和转发声明
- CNTK:->转发或 ->评估某些电脑上的崩溃,而不是其他电脑上的崩溃
- C++20理念:要求表达和完美转发
- 如何在模板中转发右值和左值引用
- 如何转发声明枚举?
- 使用函数指针转发声明作为 lamba 声明
- CAFFE转发网络在for循环中不起作用
- 如何将迭代器调用转发给类的私有成员?
- 转发复制的 std::tuple
- 完美的转发和构造函数
- 是否可以在不扣除的情况下将模板参数转发到 make_*?
- 通过基类接受方法转发派生 UniquePtr 的右值会移动引用而不是复制
- c++如何知道在状态模式中向何处转发声明