Как правильно вывести sh назад и затем oop через вектор объектов, находящихся в куче? - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть следующий класс:

#include <iostream>
#include <math.h>
#include <vector>
class minimal
{
private:
    int x;
    int y;
public:
    minimal(int x = NAN, int y = NAN)  // default constructor
    {
        this->x = x;
        this->y = y;
    }
    ~minimal(){}
    void setvals(int xin, int yin)
    {
        this->x = xin;
        this->y = yin;
    }
    int getx() {return this->x;}
};
int main() {
    // goal: create a vector of type minimal to be located in the heap
    std::vector<minimal*> vectinheap;

    minimal * min_ptr = new minimal;
    for (int i = 0; i < 4; ++i)
    {
        min_ptr->setvals(i, -i);
        vectinheap.push_back(min_ptr);  // send a local copy to vectinheap?
    }
    delete min_ptr;  // free the heap
    min_ptr = nullptr;  // free dangling pointer
    // now how to iterate through vect in heap.. ?
    return 0;
}

Из этого возникает пара вопросов:

  1. Когда я говорю vectinheap.push_back(min_ptr), это собирается сделать каждое значение в векторе указывать на тот же экземпляр в конце, или он добавит текущий экземпляр так, как я хочу?
  2. После загрузки вектора, расположенного в куче, как я могу выполнить итерацию и получить доступ к каждому экземпляру путем индексации вектора?

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

Я полагаю, вы пришли из C# или Java фона? (отсюда и причина попытки нового все?). То, как вы это сделаете в C ++, будет выглядеть примерно так:

int main() {
    // store a vector of minimal structs
    std::vector<minimal> vectinheap;

    int n = 4;
    for (int i = 0; i < n; ++i)
    {
        int xlocal = i;  // set dummy vals for filling vectinheap
        int ylocal = -i;

        // emplace_back will construct a new item at the end of the vector
        vectinheap.emplace_back(xlocal, ylocal);
    }


    // and now to iterate (range based for loop - best method)
    for(auto& value : vectinheap)
    {
      std::cout << value.getx() << ' ' <<  value.gety() << std::endl;
    }

    // the less good way using iterators
    for(auto it = vectinheap.begin(); it != vectinheap.end(); ++it)
    {
      std::cout << it->getx() << ' ' <<  it->gety() << std::endl;
    }

    // and using indices if you really must
    for(size_t i = 0; i < vectinheap.size(); ++i)
    {
      std::cout << vectinheap[i].getx() << ' ' <<  vectinheap[i].gety() << std::endl;
    }

}

Однако использование push_back / emplace_back для создания простого POD-массива - очень неэффективный подход. Обычно лучше выделить один раз заранее и просто заполнить данные. Таким образом, вы не будете постоянно задавать вопрос «могу ли я добавить еще один элемент в этот массив, не меняя его размер?» каждая итерация l oop.

    int n = 4;

    // allocate enough memory for 'n' structs
    std::vector<minimal> vectinheap(n);

    for (int i = 0; i < n; ++i)
    {
        int xlocal = i;  // set dummy vals for filling vectinheap
        int ylocal = -i;

        // just use the array brackets to access
        vectinheap[i].setvals(xlocal, ylocal);
    }
1 голос
/ 03 февраля 2020
  1. Вам лучше переименовать std::vector<minimal*> vectinheap; в vect_of_ptr, потому что вашего вектора нет в куче.
  2. Когда я говорю, что vectinheap.push_back (min_ptr) означает, что каждое значение в векторе будет указывать на один и тот же экземпляр в конце, или будет добавлять текущий экземпляр как I хочу?

Вы нажимаете указатель, который указывает на тот же minimal объект, выделенный в куче вектору vectinheap.

После загрузки вектора, находящегося в куче, как я могу выполнить итерацию и получить доступ к каждому экземпляру путем индексации вектора?

Вы делаете :

for(const auto& item: vectinheap)
{
    //item is a pointer, you can get your object by dereference it using *
}

Примечание: Вы создаете только один объект minimal в куче, но вы указываете sh четыре указателя, указывающих на него (тот же объект) в ваш вектор , И вы должны удалить объект на delete min_ptr;. И цикл по вектору и разыменование указателя в нем станет undefined .

. Вы должны исправить это, переместив minimal * min_ptr = new minimal; в свой для l oop. И не забудьте удалить их , когда вы просматриваете ваш vectinheap.

...