矢量的指针而不是对象

时间:2014-07-24 03:08:11

标签: c++ pointers vector

每次将对象放入std :: vector时,都必须复制该对象。

那么我可以只使用指针而不是像这样的对象吗?:

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

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

或者出于某种原因,这不是一个好主意?

3 个答案:

答案 0 :(得分:3)

使用智能指针向量。这样你就不会出现内存泄漏。

您所描述的方法从列表中弹出时必须小心,并且在完成后需要确保列表为空。

答案 1 :(得分:1)

您没有使用&#34; new&#34;或分配内存,所以从技术上讲,您不会有任何内存泄漏。

但是,你必须小心范围。例如,如果你有

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

你最终会得到一个指向funcFoo中对象的指针向量。离开函数后,该对象可能是垃圾。

我假设你想要的更像是这样:

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

如果是这种情况,那么您必须记住通过调用new来释放您使用delete分配的所有内存。

例如:

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

答案 2 :(得分:1)

你可以创建一个指针向量,但你必须知道,当它完成时,向量将自动调用指针上的delete。如果您的指针分配了new,则在删除元素或销毁向量之前必须自己delete,否则您将泄漏内存。确保在所有情况下都能进行清理是非常棘手的。特别是,异常会导致跳过函数末尾的清理代码。

使用智能指针向量更安全,即使遇到异常情况,它也会自动处理清理工作。在C ++ 11中,您可以创建std::unique_ptr<T>的向量。对于不支持C ++ 11的旧版编译器,您可以使用std::tr1::shared_ptr<T>boost::shared_ptr<T>代替,但这会带来一些您真正不需要的引用计数开销。你无法将C ++ 98的std::auto_ptr放在一个向量中(这就是为什么它在C ++ 11中被弃用并替换为std::unique_ptr的原因)。

此外,在C ++ 11中,您可以选择在将对象插入向量时避免复制:

  • 您可以将myvector.push_back(std::move(myobject))调用对象移动到向量中,而不是复制它。这仍然在向量中构造了一个新实例,但它允许取得myobject所持有的任何资源的所有权,而不是复制它们。之后不应使用myobject,因为它不再保留以前的数据。
  • 您可以调用myvector.emplace_back(...)将新对象直接构建到矢量存储中。这基本上是类的构造函数的包装器,并且可以给出任何有效传递给该构造函数的参数集。

请注意,如果您希望矢量具有多态性 - 也就是说,如果您希望能够将正方形和圆形存储在形状矢量中 - 那么存储指针(最好是智能指针)是您唯一的选择。实际存储在向量中的所有项必须是相同的类型,因此该类型必须类似于基类指针。