简体   繁体   English

指针而不是对象的向量

[英]vector of pointers instead of objects

Every time you put object into std::vector it has to make a copy of that object. 每次将对象放入std :: vector时,都必须复制该对象。

So can I just put pointers instead of objects like that?: 那么我可以只放置指针而不是像这样的对象吗?:

Class *ptr_Class;
Class object;
ptr_Class = &object;

std::vector<Class*> vector;
vector.push_back(ptr_Class);

Or for some reason it is not a good idea? 还是由于某种原因,这不是一个好主意?

Use a vector of smart pointers. 使用智能指针向量。 in that way you will not get memory leaks. 这样,您就不会出现内存泄漏。

The method you have described you have to be careful when popping from the list and you need to ensure that the list is empty when you have finished with it. 您所描述的方法从列表中弹出时必须要小心,并需要确保列表完成后为空。

You are not using "new", or allocating memory, so technically you won't have any memory leaks. 您没有使用“新”或分配内存,因此从技术上讲,您不会有任何内存泄漏。

However, you have to be careful with scope. 但是,您必须注意范围。 For instance, if you have 例如,如果您有

std::vector<Class*> funcFoo()
{
    Class *ptr_Class;
    Class object;
    ptr_Class = &object;
    std::vector<Class*> vector;
    vector.push_back(ptr_Class);
    return vector;
}

you will end up with a vector of a pointer that pointed to an object in funcFoo. 您将最终获得指向funcFoo中的对象的指针向量。 That object will likely be garbage after you leave the function. 离开函数后,该对象可能是垃圾。

I'm assuming that what you want is more like this: 我假设您想要的是这样的:

Class *ptr_Class = new Class();
std::vector<Class*> vector;
vector.push_back(ptr_Class);

If this is the case, then you have to remember to deallocate any memory you allocated with new by calling delete . 如果是这种情况,那么您必须记住通过调用delete来释放使用new分配的所有内存。

For instance: 例如:

for (unsigned int i = 0; i < vector.size(); ++i)
{
    delete vector[i];
    vector[i] = NULL; 
}

You can make a vector of pointers, but you have to be aware that the vector will not automatically call delete on the pointers when it's done with them. 您可以创建一个指针向量,但是必须注意,向量处理完指针后不会自动调用delete If your pointers were allocated with new , you have to delete them yourself before removing elements or destroying the vector, or you'll leak memory. 如果为指针分配了new ,则必须先delete它们,然后再删除元素或破坏向量,否则会泄漏内存。 It's tricky to make sure this cleanup happens in all cases; 确保在所有情况下都进行清理是很棘手的。 in particular, exceptions can cause cleanup code at the end of a function to be skipped. 特别是,异常可能会导致跳过函数末尾的清除代码。

It's safer to use a vector of smart pointers, which will take care of that cleanup automatically, even in the face of exceptions. 使用智能指针向量更安全,即使面对异常情况,它也会自动进行清理。 In C++11 you can just make a vector of std::unique_ptr<T> . 在C ++ 11中,您可以仅创建std::unique_ptr<T>的向量。 With older compilers that don't support C++11, you can use std::tr1::shared_ptr<T> or boost::shared_ptr<T> instead, though that has some overhead from reference-counting that you don't really need. 对于不支持C ++ 11的较旧的编译器,您可以使用std::tr1::shared_ptr<T>boost::shared_ptr<T>来代替,尽管这样做会增加引用计数的开销,但您不这样做确实需要。 You can't put C++98's std::auto_ptr in a vector (which is why it was deprecated and replaced with std::unique_ptr in C++11). 不能将C ++ 98的std::auto_ptr放在向量中(这就是为什么不建议使用它,并在C ++ 11中将其替换为std::unique_ptr )。

Also, in C++11 you have some options for avoiding the copy when inserting an object into a vector: 另外,在C ++ 11中,当将对象插入向量中时,还有一些避免复制的选项:

  • You can call myvector.push_back(std::move(myobject)) to move the object into the vector instead of copying it. 您可以调用myvector.push_back(std::move(myobject)) 对象移到向量中,而不是复制它。 This still constructs a new instance within the vector, but it's allowed to take ownership of any resources held by myobject instead of copying them. 这仍然在向量中构造了一个新实例,但是允许获取myobject拥有的任何资源的所有权,而不是复制它们。 The myobject shouldn't be used afterward, since it no longer holds the data that it used to. myobject不应再使用,因为它不再保存以前使用的数据。
  • You can call myvector.emplace_back(...) to construct a new object directly into the vector's storage. 您可以调用myvector.emplace_back(...)将一个新对象直接构造到向量的存储中。 This is basically a wrapper for your class's constructor, and can be given any set of arguments that are valid to pass to that constructor. 基本上,这是类的构造函数的包装,并且可以给任何有效传递给该构造函数的参数集。

Note that if you want your vector to be polymorphic — that is, if you want to be able to store both squares and circles in a vector of shapes — then a storing pointers (preferably smart pointers) is your only option. 请注意,如果您希望向量是多态的(即,如果您希望将正方形和圆形都存储在形状的向量中),那么存储指针(最好是智能指针)是您唯一的选择。 All items actually stored within a vector must be the same type, so that type has to be something like a base-class pointer. 向量中实际存储的所有项目都必须是相同的类型,因此该类型必须类似于基类指针。

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

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