Создание вектора указателей 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);
}