指向vector的指针vs指向vector的指针vs指向vector的指针
Pointer to vector vs vector of pointers vs pointer to vector of pointers
只是想知道您认为c++中关于向量的最佳实践是什么。
如果有一个包含vector成员变量的类。什么时候声明这个向量a:
- 包含值的"全对象"矢量成员变量,即
vector<MyClass> my_vector;
- 指向矢量的指针,即
vector<MyClass>* my_vector;
- 指针向量,即
vector<MyClass*> my_vector;
- 指向指针向量的指针,即
vector<MyClass*>* my_vector;
我在我的一个类中有一个具体的例子,我目前已经声明了一个向量作为案例4,即vector<AnotherClass*>* my_vector;
其中AnotherClass是我创建的另一个类。
MyClass::MyClass()
: my_vector(new vector<AnotherClass*>())
{}
在析构函数中,我做了以下操作:
MyClass::~MyClass()
{
for (int i=my_vector->size(); i>0; i--)
{
delete my_vector->at(i-1);
}
delete my_vector;
}
向量的元素是在我的类的一个方法中添加的。我无法提前知道有多少物体会被添加到向量中。这是在代码执行时根据解析xml文件决定的。
这是好的做法吗?还是应该将vector声明为其他情形1、2或3中的一种?
何时使用哪个case?
我知道,如果vector的元素是另一个类(多态性)的子类,则它们应该是指针。但是在其他情况下应该使用指针吗?
非常感谢!
通常解决方案1是你想要的,因为它是c++中最简单的:你不需要管理内存,c++为你做了所有这些(例如,你不需要提供任何析构函数)。
在特定的情况下,这不起作用(最明显的是在处理多态对象时),但通常这是唯一的好方法。
即使在处理多态对象或需要堆分配对象时(无论出于何种原因),原始指针几乎都不是一个好主意。相反,使用智能指针或智能指针的容器。现代c++编译器从即将发布的c++标准中提供shared_ptr
。如果您使用的编译器还没有这个功能,那么您可以使用Boost中的实现。
绝对是第一!
使用vector进行自动内存管理。使用指向矢量的原始指针意味着你不再获得自动内存管理,这是没有意义的。
关于值类型:所有容器基本上都采用类值语义。同样,当你使用指针时,你需要做内存管理,而vector的目的就是为你做这些。这在《c++编码标准》一书的第79项中也有描述。如果您需要使用共享所有权或"弱"链接,请使用适当的智能指针。
手动删除vector中的所有元素是一种反模式,并且违反了c++中的RAII习惯用法。因此,如果你必须在vector
中存储指向对象的指针,最好使用"智能指针"(例如boost::shared_ptr
)来方便资源销毁。例如,当对对象的最后一个引用被销毁时,boost::shared_ptr
会自动调用delete
。
也不需要使用new
来分配MyClass::my_vector
。一个简单的解决方案是:
class MyClass {
std::vector<whatever> m_vector;
};
假设whatever
是一个智能指针类型,不需要做额外的工作。就是这样,当MyClass
实例的生命周期结束时,所有的资源都会被自动销毁。
在许多情况下,你甚至可以使用普通的std::vector<MyClass>
——这是在vector中的对象可以安全复制的情况下。
在您的示例中,vector在创建对象时创建,在对象销毁时销毁。这正是使vector
成为类的普通成员时所得到的行为。
同样,在当前的方法中,在复制对象时会遇到问题。默认情况下,指针将导致平面复制,这意味着对象的所有副本将共享相同的向量。这就是为什么,如果你手动管理资源,你通常需要Big Three。
指针向量在多态对象的情况下是有用的,但是您应该考虑其他替代方法:
- 如果矢量拥有对象(这意味着它们的生命周期受矢量的生命周期限制),您可以使用
boost::ptr_vector
。 - 如果对象不属于矢量,可以使用
boost::shared_ptr
的矢量,也可以使用boost::ref
的矢量。
指向vector
的指针很少有用——vector
的构造和销毁都很便宜。
对于vector
中的元素,没有正确答案。vector
多久改变一次?复制构造vector
中的元素需要多少成本?其他容器是否有指向vector
元素的引用或指针?
vector
中存储基类的各种子类的情况将需要指针。
如果您的设计要求您使用指针作为vector
元素,那么像boost::shared_ptr
这样的引用计数智能指针可能是最佳选择。
复杂的答案:看情况。
如果你的vector是共享的,或者它的生命周期与嵌入它的类不同,那么最好将它保留为指针。如果您引用的对象没有(或有昂贵的)复制构造函数,那么最好保留指针的向量。相反,如果您的对象使用浅复制,使用对象的向量可以防止泄漏…
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 当该数组的索引中没有元素时,指针指向什么?
- 我无法使用C++指针指向类方法返回的 std::vector
- 指针指向的数组的大小
- 从另一个指针指向函数的指针
- 使用指针指向对象C++对向量进行排序
- 为什么下面的代码段返回指针指向的值而不是指针的地址?
- 使用智能指针指向 C 库中的结构,该结构通过 typedef 隐藏实现(即不完整的类型)
- 为什么编译器C++不能知道指针指向派生类?
- 如何防止基类的指针指向派生类?
- 为什么第一次迭代后的指针指向随机值?
- 为什么使用父指针指向子类?
- 数组由其类自己的指针指向的大小是多少?
- 变量更改后,如何保持指针指向的初始值
- C++ 常量用于指针指向指针
- 这个指针指向给定的对象还是给定对象的地址
- 静态指针指向这个为mock for googletest定义的类内部
- 指针(指向指针)和新/malloc 向量(向量内部)c++
- 确保指向超类的指针指向c++中某个子类的对象
- 奇怪的指针指向某物模板参数