【问题标题】:Why doesn't C++ require a "new" statement to initialize std::vector?为什么 C++ 不需要“new”语句来初始化 std::vector?
【发布时间】:2012-01-29 09:48:55
【问题描述】:

考虑:

/* bar.h */
class bar{
    /* Standard stuff omitted */
    std::vector<my_obj*> foo;
};

/* bar.cpp */
bar::bar(){
    // foo = new std::vector<my_obj*>(); <-- Why don't I need this line??
    foo.push_back(new my_obj());
}

为什么即使我们没有为 foo 分配一个新的 std::vector 实例,这段代码仍然有效?

【问题讨论】:

  • 他们所说的。另外,我不能推荐foo.push_back(new my_obj());,因为你要去哪里释放内存?

标签: c++ stl stdvector


【解决方案1】:

因为 C++ 不是 C#/Java。

std::vector<my_obj*> foo;

这是一个对象的定义,而不是C#/Java中的引用。对象是类型的一个活生生的实例。

new std::vector<my_obj*>()

这个表达式返回一个指针。它返回一个std::vector&lt;my_obj*&gt;*,它不是foo 相同的类型(最后的* 是它们不同的原因)。 foo 是一个对象,std::vector&lt;my_obj*&gt;* 是一个指向对象的指针。

对象(而不是指针或引用)具有特定的生命周期。如果您使用new 创建指向对象的指针,则指向的对象的生命周期将一直持续到您显式调用delete。如果您创建一个对象作为另一个对象的成员,那么该内部对象的生命周期将(或多或少)反映外部对象的生命周期。如果您在堆栈上创建一个对象(函数范围内的参数或变量),那么它的生命周期就是该变量名称的当前范围。

【讨论】:

    【解决方案2】:

    因为bar 包含std::vector,而不是std::vector *

    真的和这样的没有什么不同:

    class bar
    {
        int foo;  // No need to create a "new int"
    };
    

    【讨论】:

      【解决方案3】:

      因为 foo 是一个对象,而不是一个指针。

      std::vector<my_obj*>    // This is an object
      std::vector<my_obj*> *  // This is a pointer to an object
                          ^^^ // Notice the extra star.
      

      new 返回一个指针:

      new std::vector<my_obj*>();  // returns std::vector<my_obj*> *
      

      附言。您的向量可能应该包含对象,而不是指针。

      std::vector<my_obj>   foo;
      ...
      foo.push_back(my_obj());
      

      否则,当向量超出范围时(当包含对象被销毁时),您将需要手动删除向量中的所有对象。即,如果您想在向量中保留指针,您应该执行以下操作之一:

      // 1. Manually delete all the elements in the vector when the object is destroyed.
      ~bar::bar()
      {
          for(std::vector<my_obj*>::iterator loop = foo.begin(); loop != foo.end(); ++loop)
          {
              delete (*loop);
          }
      }
      
      // 2. Use a smart pointer:
      std::vector<std::shared_ptr<my_obj> >  foo;
      
      // 3. Use a smart container for pointers
      boost::ptr_vector<my_obj>   foo
      

      【讨论】:

        【解决方案4】:

        因为std::vector 会为你做这件事:) 你没有指向std::vector 的指针,你只是设置了一个std::vector 类型的对象,它会在内部为你分配内存。

        【讨论】:

          【解决方案5】:

          您不需要在 foo 上使用 new,因为 foo 是 vector,而不是指向 vector 的指针(即 std::vector&lt;my_obj*&gt; *foo)。

          如果您来自 Java 或 C#,您可能需要考虑使用 std::vector&lt;my_obj&gt;(对象向量)而不是指针向量。这真的取决于你想做什么。

          【讨论】:

            【解决方案6】:

            std::vector&lt;my_obj *&gt; foostd::vector&lt;my_obj *&gt; *foo 不同。第二种情况需要你使用 new 而第一种不需要。

            【讨论】:

              【解决方案7】:

              std::vector 在这个库中不是指针。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-10-26
                • 2020-10-28
                • 1970-01-01
                • 2017-03-15
                • 2022-06-10
                • 2017-12-21
                • 2013-06-06
                • 2020-10-10
                相关资源
                最近更新 更多