繁体   English   中英

auto_ptr和containers - C ++

[英]auto_ptr and containers - C++

我目前正在研究2D游戏引擎,我已经阅读了auto_ptr以及你应该如何将它们放在标准容器中。

我的引擎有这样的结构:

StateManager - 有很多 - > State's。

在引擎外部的main中创建和分配状态。 我希望引擎存储所有状态的列表/向量,以便我可以在命令之间进行更改。

例如:


SomeState *test = new SomeState();
StateManager->registerState(test);

由于状态只在应用程序死亡时死亡,我可以使用这种方法吗?


std::auto_ptr<SomeState> test(new SomeState());
StateManager->registerState(test.get());

// Inside StateManager State *activeState; // State manager then maintains a vector std::vector<State*> stateList; // and upon registerState it adds the pointer to the vector void registerState(State *state) { stateList.push_back(test); }

StateManager应该只维护一个指向状态的指针向量,它不需要取得所有权。 当我想改变引擎中的状态时,我只需将activeState指针更改为指向stateList向量中找到的所需状态。

这是一个糟糕的方法吗?

为什么不使用std :: vector <State>而不担心存储指针? 听起来状态列表是固定的,因此在程序的生命周期内任何迭代器都不会失效。

或者,我发现Boost指针容器库对这类事情很有用。

由于StateManager不拥有包含的对象,因此其包含的类型应为State *,而不是智能指针。 在main函数中使用auto_ptr是可以的,这与StateManager容器无关。

如果您希望拥有负责包含对象生命周期的容器,则可以将智能指针用作包含类型。 但是使用auto_ptr对此很危险,因为它具有原始所有权算法。 最好在这样的容器中使用shared_ptr。

如果没有什么可以排除它(多态性等),那么我只使用最简单的方法,即std::vector<State> activeState仍然可以是指针(或迭代器)。

在您发布的代码中使用auto_ptr的方式不起作用。

std::auto_ptr<SomeState> test(new SomeState());
StateManager->registerState(test.get());

当“test”变量超出范围时,将调用其析构函数,该析构函数将删除刚刚使用StateManager注册的SomeState对象。 所以现在你的StateManager保持一个指向已删除对象的指针,这可能会导致崩溃。

相反,您可以考虑使用引用计数器智能指针类型,例如boost :: shared_ptr

auto_ptr应该在指定的上下文中管理对象的生命周期。 例如

void foo(){MyObject * pNewObject = new MyObejct;

//做一些删除pNewObject; }

在上面的函数中,如果在// Do Something代码中发生了一些异常,则该对象将不会自由d并且您将在代码中面临内存泄漏。 我们在这种情况下使用Auto_ptrs。

但它不适合以下上下文(释放数组)。 在auto_ptr的析构函数中,它调用delete ptr; 但是对于数组,我们必须调用delete [] ptr; 如果将auto_ptr与数组一起使用,将发生内存泄漏并导致意外行为void foo(){

unsigned char * pStream = new unsigned char [size]; ....

delete [] pStream; }

如果你没有多少状态并且内存不那么贪心,我建议你使用Singleton对象作为你的状态类。 所以你不必担心内存管理。 状态管理器可以处理活动状态和状态对象,但我认为在状态管理器外部初始化状态对象并在状态管理器和其他地方执行其余操作并不是一个好主意。 请确保统一创建和销毁

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM