Создание вектора указателей c++
в моем коде C++ У меня есть объект класса, оснащенный полем id типа int. Теперь я хочу создать вектор указателей типа Object*. Сначала я попробовал
vector<Object*> v;
for(int id=0; id<n; id++) {
Object ob = Object(id);
v.push_back(&ob);
}
но это не удалось, потому что здесь тот же адрес просто повторяется n раз. Если бы я использовал новый оператор, я бы получил то, что хочу, но я хотел бы избежать динамического выделения памяти. Затем я подумал, что мне нужно как-то объявить n разных указателей перед циклом for. Прямой путь к этому - объявите массив, чтобы я сделал это:
vector<Object*> v;
Object ar[n];
for(int i=0; i<n; i++) {
ar[i] = Object(i);
}
for(int i=0; i<n; i++) {
v.push_back(ar+i);
}
есть ли еще возможность получить утечку памяти, если я делаю это таким образом? Также прохождение объявления массива, на мой взгляд, немного неуклюже. Есть ли другие способы создания вектора указателей, но избежать ручного управления памятью?
EDIT: почему мне нужны указатели вместо простых объектов?
Ну, я немного изменил исходную фактическую ситуацию, потому что я думал, что таким образом я могу представить вопрос в самой простой форме. Во всяком случае, я все еще думаю, что на вопрос можно ответить, не зная, почему я хочу вектор указателей.
на самом деле у меня есть
Class A {
protected:
vector<Superobject*> vec;
...
};
Class B: public A {...};
Class Superobject {
protected:
int id;
...
}
Class Object: public Superobject {...}
в производном классе B
Я хочу заполнить поле участника vec
С объектами типа Object
. Если бы суперкласс не использовал указатели, у меня были бы проблемы с нарезкой объектов. Так в классе B
конструктор я хочу, чтобы инициализировать vec
как вектор указателей типа Object*
.
EDIT2
Да, мне кажется, что динамическое распределение является разумным вариантом, и идея использовать массив-это плохая идея. Когда массив выходит за рамки, все пойдет не так, потому что указатели в векторе указывают на места памяти, которые больше не обязательно содержат объекты.
в конструкторе для класса B у меня было
B(int n) {
vector<Object*> vec;
Object ar[n];
for(int id=0; id<n; id++) {
ar[id] = Object(id);
}
for(int id=0; id<n; id++) {
v.push_back(ar+id);
}
}
это вызвало очень странное поведение в объектах класса B.
3 ответов
в этом цикле:
for(int id=0; id<n; id++) {
Object ob = Object(id);
v.push_back(&ob);
}
вы создаете N раз экземпляр объекта в стеке. На каждой итерации создается и удаляется элемент. Вы можете просто избежать этого, используя это:
for(int id=0; id<n; id++) {
Object* ob = new Object(id);
v.push_back(ob);
}
спасибо, что каждый новый элемент существует на куче а не в стеке. Попробуйте добавить в конструктор объектов класса что-то вроде этого:
std::cout<<"Object ctor()\n";
и то же самое в деструкторе:
std::cout<<"Object dtor()\n";
если вы не хотите создавать эти объекты с помощью" новой " причины автор: @woolstar
Ваш вопрос об утечках памяти заставляет меня думать, что вы беспокоитесь о жизненном цикле и уборке этих объектов. Я изначально предложил shared_ptr
обертки, но C++11 дал нам unique_ptr
, а C++14 заполнил недостающее make_unique
. Итак, со всем, что мы можем сделать:
vector<unique_ptr<SuperObject>> v ;
который вы создаете на месте с чудесностью совершенной переадресации и вариативных шаблонов,
v.push_back( make_unique<Object>( ... ) ) ;
да вам придется жить с некоторыми выделений, но все будет убрали, когда v
уходит.
кто-то предложил увеличить библиотеке, ptr_container
, но для этого требуется не только добавить импульс к вашему проекту, но и обучить всех будущих читателей, что это ptr_container
это и делает.
нет в вашей версии нет утечки памяти. Когда программа покидает вашу область действия, вектор, а также массив уничтожаются. На ваш второй вопрос: почему бы просто не хранить объекты непосредственно в вектор?
vector<Object> v;
for(int i = 0; i < n; i++)
{
Object obj = Object(i);
v.push_back(obj);
}