Why doesn't C++ require a “new” statement to initialize std::vector?

烈酒焚心 提交于 2021-02-05 19:55:44

问题


/* 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());
}

Why does this code work even though we didn't assign foo a new instance of std::vector ?


回答1:


Because C++ is not C#/Java.

std::vector<my_obj*> foo;

This is a definition of an object, not a reference as in C#/Java. An object is a living instance of a type.

new std::vector<my_obj*>()

This expression returns a pointer. It returns a std::vector<my_obj*>*, which is not the same type as foo (the * at the end is what makes them different). foo is an object, std::vector<my_obj*>* is a pointer to an object.

Objects (rather than pointers or references) have specific lifetimes. If you create a pointer to an object with new, the lifetime of the object pointed to will be until you explicitly call delete. If you create an object as a member of another object, then that inner object's lifetime will (more or less) mirror the outer object's lifetime. If you create an object on the stack (a parameter or variable at function scope), then its lifetime is the current scope of that variable name.




回答2:


Because bar contains a std::vector, not a std::vector *.

It's really no different to something like this:

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



回答3:


Because foo is an object not a pointer.

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

New rerturns a pointer:

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

PS. You vector should probably contain objects not pointers.

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

Otherwise you will need to manually delete all the objects in the vector when it goes out of scope (when the containing object is destroyed). ie if you want to keep pointers in your vector you should do one of the following:

// 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:


Because std::vector does that for you :) You don't have a pointer to std::vector, you're simply setting up an object of type std::vector, which internally allocates memory for you.




回答5:


std::vector in this library is not a pointer




回答6:


You do not need to use new on foo, since foo is a vector, not a pointer to a vector (i.e. std::vector<my_obj*> *foo).

If you are coming from Java or C#, you may want to consider using std::vector<my_obj> (a vector of objects) instead of a vector of pointers. It really depends on what you want to do.




回答7:


std::vector<my_obj *> foo is different from std::vector<my_obj *> *foo. The second case will require you to use new while the first wll not.



来源:https://stackoverflow.com/questions/8660025/why-doesnt-c-require-a-new-statement-to-initialize-stdvector

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!