Почему нет необходимости использовать "новый" для инициализации 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>
(вектор объектов) вместо вектора указателей. Это действительно зависит от того, что вы хотите сделать.