引用运算符与shared_ptr C++11的误解
Reference operator and shared_ptr C++11 misunderstanding
我正在努力提高我的C++知识,需要帮助理解一些带有引用指针和shared_ptr
的构造。
我有一个这样的结构:
IState *m_Loader;
void CStateManager::AttachState(E_STATE _estate, const IState &_state)
{
switch(_estate)
{
case STATE_LOADER:
m_Loader = _state;
break;
}
}
编译器告诉我,它无法将"Const IState
转换为IState*
"——我如何保存对象,以便以后使用它?我试着把自己从旧C语言的指针中解放出来,使用现代C++。
第二个问题是如何使用shared_ptr
来实现状态模式?我看到使用shared_ptr
是不可靠的,可能我需要weak_ptr
,但我仍然无法想象如何实现这一点。
这里有完整的源代码,以了解我试图实现的内容。
#pragma once
#include <memory>
class IState;
class IStateManager
{
public:
enum E_STATE
{
STATE_LOADER,
STATE_MENU,
STATE_GAME,
STATE_EXIT
};
virtual void SwitchState(E_STATE _estate) = 0;
virtual void AttachState(E_STATE _estate, const IState &_state) = 0;
virtual void Update() = 0;
public:
virtual ~IStateManager() {}
};
class IState
{
public:
virtual void Enter(const IStateManager &_statemgr) = 0;
virtual void Exit() = 0;
virtual void Sleep() = 0;
virtual void Update() = 0;
public:
virtual ~IState() {}
};
class CStateManager: public IStateManager
{
public:
void SwitchState(E_STATE _estate);
void AttachState(E_STATE _estate, const IState &_state);
void Update();
~CStateManager();
private:
IState *m_Loader;
IState *m_Menu;
IState *m_Game;
IState *m_Exit;
};
;
void CStateManager::SwitchState(E_STATE _estate)
{
}
void CStateManager::AttachState(E_STATE _estate, const IState &_state)
{
switch(_estate)
{
case STATE_LOADER:
m_Loader = _state;
break;
case STATE_MENU:
break;
case STATE_GAME:
break;
case STATE_EXIT:
break;
}
}
void CStateManager::Update()
{
}
CStateManager::~CStateManager()
{
}
您最关心的是所引用对象的生存期,无论您使用引用、原始指针还是shared_ptr
,都可能遇到问题,例如:
CStateManager test()
{
CStateManager result;
IState localIState;
result.AttachState( CStateManager::STATE_LOADER, localIState );
return result;
}
int main()
{
CStateManager badLoader = test();
return 0;
}
在main
函数中,如果访问了badLoader::m_Loader
,则会出现segfault,因为m_Loader是指向已不存在的内存位置的指针。如果m_Loader
是一个参考,甚至是一个shared_ptr
,那么同样的事情显然也是正确的。
避免segfault的方法是使用m_Loader
作为weak_ptr
。所以你的代码会变成这样:
std::weak_ptr< IState > m_Loader;
void CStateManager::AttachState(E_STATE _estate, std::weak_ptr< IState > _state)
{
switch(_estate)
{
case STATE_LOADER:
m_Loader = _state;
break;
}
}
在调用函数中,您还必须更改创建localIState
:的方式
CStateManager test()
{
CStateManager result;
std::shared_ptr< IState > localIState( new IState );
result.AttachState( CStateManager::STATE_LOADER, localIState );
return result;
}
如果您在main
中访问badLoader::m_Loader
,这将保护您免受分段故障的影响,因为std::weak_ptr
在访问之前总是会检查其目标的存在。
相关文章:
- MSVC是否支持C++11样式的属性而不是__declspec
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 如何将模板转换为C++11之前的模板
- c++11评估顺序(未定义的行为)
- C++中的VLA,扩展名为std=C++11
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- "类模板示例<int>;"语句对 C++11 是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 如何使用lock_guard在c++11中实现scoped_lock功能
- C++11 中不同类型的对象的 std::array 的替代方案
- 为什么 -mmacosx-version-min=10.10 不阻止使用标记为从 10.11 开始的函数?
- 为什么我的C++代码中出现'Segmentation Fault: 11'行?
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- STLPort using C++11
- MSVC 19.11 / Visual C 2017:尺寸1和size_t类型的初始化列表误解
- C++11动态数组部分列表初始化(错误或误解)
- 引用运算符与shared_ptr C++11的误解