为什么C++不需要"new"语句来初始化std :: vector?

ash*_*ash 32 c++ stl stdvector

/* 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());
}
Run Code Online (Sandbox Code Playgroud)

为什么这个代码工作,即使我们没有为foo :: vector的新实例分配foo?

Nic*_*las 49

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

std::vector<my_obj*> foo;
Run Code Online (Sandbox Code Playgroud)

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

new std::vector<my_obj*>()
Run Code Online (Sandbox Code Playgroud)

该表达式返回一个指针.它返回一个std::vector<my_obj*>*,这是为同一类型foo(与*在到底是什么让他们有所不同).foo是一个对象,std::vector<my_obj*>*是一个指向对象的指针.

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


Oli*_*rth 6

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

这样的事情真的没有什么不同:

class bar
{
    int foo;  // No need to create a "new int"
};
Run Code Online (Sandbox Code Playgroud)


Mar*_*ork 5

因为foo是对象而不是指针。

std::vector<my_obj*>    // This is an object
std::vector<my_obj*> *  // This is a pointer to an object
                    ^^^ // Notice the extra star.
Run Code Online (Sandbox Code Playgroud)

新的返回指针:

new std::vector<my_obj*>();  // returns std::vector<my_obj*> *
Run Code Online (Sandbox Code Playgroud)

PS。向量可能应该包含对象而不是指针。

std::vector<my_obj>   foo;
...
foo.push_back(my_obj());
Run Code Online (Sandbox Code Playgroud)

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

// 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
Run Code Online (Sandbox Code Playgroud)