为啥 C++ 不需要“new”语句来初始化 std::vector?

Posted

技术标签:

【中文标题】为啥 C++ 不需要“new”语句来初始化 std::vector?【英文标题】: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());,因为你要去哪里释放内存? 【参考方案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 在这个库中不是指针。

【讨论】:

以上是关于为啥 C++ 不需要“new”语句来初始化 std::vector?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 C++ 中用 new 调用参数化构造函数?

我不知道为啥我不能在 C++ 中初始化一个数组的数组

为啥调用 std:map:clear 后内存占用率没有降低

C语言中已经有了malloc和free,为啥还需要new和delete?

关于 std::cout,为啥使用“外部”而不是“单例模式”

java里面为啥总要new,不new为啥不行?scanner scancer=new scan