我一直在研究RAII(http://tomdalling.com/blog/software-design/resource-acquisition-is-initialisation-raii-explained/)并提出了许多问题!
在堆栈上初始化对象时有一些强有力的参数。在堆上分配内存是否有好的方案?
这对多态对象有何影响?例如,您有一个名为Biome
的抽象基类,您需要一个生物群系列。这个容器需要存储Ocean
,Tundra
,Desert
等对象。是否有任何问题或强有力的论据反对在堆栈上分配这些对象,但是然后存储指向这些对象的指针指向生物群系的指针容器? 我知道一旦封装对象超出范围,这些对象将被销毁,其指针将被发送到可能不存在的内存中。
答案 0 :(得分:2)
有一些强大的参数可以初始化堆栈上的对象。在堆上分配内存是否有好的方案?
当对象数量或其实际类型仅在运行时(不是在编译时)或大时才知道时,您当然需要在堆中分配对象。你不希望有大call stack frames(典型的帧应该小于一千字节,因为整个堆栈小于2兆字节,你可以有递归,或者只是非常深的函数)。
这如何与多态对象一起使用?例如,您有一个名为Biome的抽象基类,您需要一个生物群系列。这个容器需要存放海洋,苔原,沙漠等物体。
您的容器实际上会存储指向这些对象的指针。当然,您可能希望拥有智能指针。
答案 1 :(得分:0)
没有。 RAII基于自动对象销毁,即由编译器自动插入的析构函数调用。 (编辑:我希望你的问题只是关于堆+ RAII,而不是一般的堆!)
不是很好。根据我的经验,多态类通常不适合RAII,因为多态类对象的对象生命周期通常与范围不对应。如果生命周期与范围相对应,则RAII仅为真正的RAII。
以下是您的示例的三种可能方案:
第一个程序逻辑:对象在死亡时知道自己,对外部事件作出反应。在这种情况下,他们会通知他们的容器消亡,然后拨打delete this
。
第二个程序逻辑:容器管理它们的生命周期,在这种情况下容器会在其析构函数中的每个元素上调用delete:
for (auto element : m_elements) {
delete element;
}
(用C ++ 11语法编写)
第三个程序逻辑:对象由各种不同的组件拥有,而不仅仅是容器,它们只有在最后一个组件死亡时才会死亡。在这种情况下,您可能会发现std::shared_ptr
(或前C ++ 11中的boost::shared_ptr
)很有用。
重点是:这些场景中没有一个与RAII有任何关系,因为在每个场景中,生命周期都与范围不对应。