我有一组多态对象,都来自我的Animal类:Cat,Dog和MonkeyFish.
我通常的操作模式是将这些对象存储在Animal指针的向量中,如下所示:
std :: vector
my_vector.push_back( new Animal_Cat() ); my_vector.push_back( new Animal_Dog() ); my_vector.push_back( new Animal_MonkeyFish() );
生活很美好......或者是它?
我最近被告知我应该尽量避免以这种方式分配内存,因为它使内存管理成为一件苦差事.当我需要销毁my_vector时,我必须遍历所有元素并删除所有内容.
我不认为我可以存储引用的向量(我可能错了),所以看起来存储Animal对象的向量是我唯一的选择.
我什么时候应该选择使用指针向量与对象向量?一般来说,哪种方法更可取?(我想尽可能减少对象复制.)
你应该尽可能使用对象向量; 但在你的情况下,这是不可能的.
指针容器可以避免切片问题.但是你必须在每个元素上调用delete,就像你正在做的那样.这很烦人但可能.不幸的是,有些情况(当抛出异常时)您无法确定是否正确调用了删除,并最终导致内存泄漏.
主要解决方案是使用智能指针.Pre-C++ 11附带auto_ptr
,但不能在标准容器中使用.C++ 11已经std::unique_ptr
和std::shared_ptr
其被设计为在容器(我喜欢可用std::unique_ptr
除非我确实需要引用计数).如果你不能使用C++ 11,最好的解决方案是Boost智能指针.
在这种情况下,存储一个Animal
对您不起作用的向量,因为您的动物具有不同的大小,并且您将无法将派生对象存储在用于保存基类的空间中.(即使它们的大小相同,也不会获得预期的多态效果,因为基类方法将被执行 - 除非您通过指针或引用访问它,否则方法的虚拟性不起作用. )
如果你想避免自己管理内存的麻烦,你可以考虑存储一个智能指针,如shared_ptr(注意auto_ptr不能与STL容器一起工作,根据Max Lybbert)或其某些变体.这样你仍然可以使用你的多态类,但这对你来说不那么重要了.
关于何时使用对象和指针没有真正严格的规则,尽管值得注意的是,在某些情况下,像你的一样,对象根本不适合你.我倾向于在没有任何事情排除它的情况下使用对象,尽管你必须关注昂贵的复制操作,因为你注意到(虽然有时它们可以通过引用传递容器来改善).
不要将shared_ptr与标准STL容器一起使用,而是查看Boost指针容器库.它旨在解决这个问题.