【问题标题】:std::vector, constructors, objectsstd::vector、构造函数、对象
【发布时间】:2011-02-03 22:17:23
【问题描述】:

下面的构造函数

 std::vector<Object> objects(n);

创建 n 个调用默认构造函数的对象,例如:

std::vector <Object> objects;
for (unsigned int i = 0; i < n; i++) objects.push_back(o);

这个过程对动态分配的对象也有效吗?是否施工

std::vector<Object *> objects(n);

代表这个功能?

std::vector <Object*> objects;
for (unsigned int i = 0; i < n; i++) objects.push_back(new Object());

如果没有,有办法安排吗?

【问题讨论】:

  • 仅供说明:除了每个push_back() 重新分配向量的内部缓冲区外,其他类似。构造一个 vector 传递缓冲区分配一次的元素数。

标签: c++ pointers stl constructor vector


【解决方案1】:
std::vector<Object> objects(n); 

其行为取决于您的标准库实现实现的 C++ 标准版本:

  • 在 C++03 中,这会创建一个默认构造的 Object,然后将该构造复制 n 次。

  • 在 C++0x 中,此默认构造 n Objects。

差异通常不重要,但很高兴知道。


std::vector<Object *> objects(n);  

这将创建一个 vector,其中包含 n 个空 Object*s。由于Object* 不是类类型并且没有构造函数,因此新插入的对象是值初始化的,对于指针意味着它们被设置为NULL

如果要动态创建新对象,然后将指向它们的指针存储在容器中,则需要自己调用new。请注意,如果容器拥有指向的对象,则不应将原始指针存储在标准库容器中。这样做不是异常安全的。

您应该改用 shared_ptrunique_ptr 之类的智能指针(注意:由于其不寻常的复制语义,auto_ptr 智能指针不能存储在容器中,因此 shared_ptrunique_ptr 应该是使用)。

无论如何,要将指向 n 个不同的、动态分配的对象的指针插入容器中,您需要调用 new n 次来创建这 n 个对象。您的for 循环解决方案没有任何问题。

【讨论】:

  • 一个重要的例子是struct dumb { int i; dumb() { static int j = 0; i = j++; } }; int main(void) { std::vector&lt;dumb&gt; v(2); std::cout &lt;&lt; v[1].i &lt;&lt; std::endl; },它将在 C++03 中打印 0,但在 C++0x 中打印 1。
【解决方案2】:

下面的构造函数

std::vector<Object> objects(n);

调用默认构造函数创建 n 个对象

可以,但是默认构造函数只用于构造vector的构造函数的第二个可选参数,向量中的n对象是通过复制这个参数来构造的。 [C++03答案]

如果你做了类似的事情:

std::vector<Object*> objects(n, new Object());

您将动态分配一个对象并在您的vector 中拥有指向该对象的n 指针,这可能不是您想要的。

如果容器应该拥有动态分配的对象,那么使用指针容器几乎总是一个坏主意。您应该考虑类似boost::ptr_vector 之类的东西,或者如果不可能的话,可以使用智能指针容器(但不是std::auto_ptr)。

【讨论】:

    【解决方案3】:

    不,vector 不会使用指向 Object 实例的指针自动创建。您必须执行您编写的for 循环才能正确填充它。

    当您完成这些对象时,您还需要delete

    【讨论】:

      【解决方案4】:

      您的最终代码示例具有正确的总体思路,但请谨慎行事:vector不会为您管理分配!例如,objects.clear() 会泄漏内存。

      您可能想改用std::vector&lt;some_smart_ptr&lt;Object&gt; &gt;,但选择正确的智能指针类需要注意(例如)当您将元素从一个向量复制到另一个向量时会发生什么。 boost::shared_ptr 是一个安全的选择,但可能会对您的用例产生不必要的开销。 boost::ptr_vector 可能会更好。

      【讨论】:

      • vector 根本不会进行任何分配,指针将被初始化为 null。
      • OP 的最终代码示例(创建向量,然后在循环中调用newpush_back)清楚地表明他们意识到了这一点。
      猜你喜欢
      • 1970-01-01
      • 2013-12-08
      • 1970-01-01
      • 1970-01-01
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 2018-03-12
      相关资源
      最近更新 更多