Почему нет необходимости использовать "новый" для инициализации std::vector?

/* 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?

Ответы

Ответ 1

Потому что С++ не является С#/Java.

std::vector<my_obj*> foo;

Это определение объекта, а не ссылка как на С#/Java. Объект является живым экземпляром типа.

new std::vector<my_obj*>()

Это выражение возвращает указатель. Он возвращает std::vector<my_obj*>*, который не является тем же типом, что и foo (в конце концов * делает их разными). foo является объектом, std::vector<my_obj*>* является указателем на объект.

Объекты (а не указатели или ссылки) имеют конкретные сроки жизни. Если вы создаете указатель на объект с 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 std::vector<my_obj*>();  // returns std::vector<my_obj*> *

PS. Вы, скорее всего, должны содержать объекты, не указатели.

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

std::vector в этой библиотеке не указатель

Ответ 6

std::vector<my_obj *> foo отличается от std::vector<my_obj *> *foo. Второй случай потребует, чтобы вы использовали новый, а первый wll не был.

Ответ 7

Вам не нужно использовать new на foo, так как foo - это vector, а не указатель на vector (т.е. std::vector<my_obj*> *foo).

Если вы используете Java или С#, вам может потребоваться использовать std::vector<my_obj> (вектор объектов) вместо вектора указателей. Это действительно зависит от того, что вы хотите сделать.