Использование массива указателей в качестве параметра метода - PullRequest
1 голос
/ 27 ноября 2011

Мне нужно использовать массив указателей на объекты, и я также должен передать его в качестве параметра методам.Однако способ сделать это ускользает от меня.Вот метод, который я использую для инициализации элементов массива.Когда я разыскиваю их в основном, их данные не верны (они содержат адреса памяти).Какой правильный путь?Может ли это быть ложным, если я разыменую их?

void createSquares(Square* squareArray[]){

    PropertySquare PropertySquare1(1,"purple",120);
    PropertySquare PropertySquare2(2,"purple",170);

    squareArray[1] = &PropertySquare1;
    squareArray[2] = &PropertySquare2;
.
.
.
}

На основном:

Square *allSquares[22] ;
createSquares(allSquares);

cout<<"ID is: "<<allSquares[1]->getID()<<endl;
cin.get();

Как я уже сказал, идентификатор, наконец, является адресом памяти.


Обновление на основе ответов:

Я пробовал это, и это не работает так же. Для меня обязательно использовать полиморфизм.

vector<Square*> allSquares;
createSquares(allSquares);

void createSquares(vector<Square*> &squares){

PropertySquare PropertySquare1(1,"purple",120);
PropertySquare PropertySquare2(2,"purple",170);

squares.push_back(&PropertySquare1);
squares.push_back(&PropertySquare2);

}

в основном:

for (vector<Square*>::iterator it=allSquares.begin(); it!=allSquares.end();it++){
   it->
}

Это не позволяет мне использовать виртуальные функции Square, поскольку он абстрактный.Любое предложение?

Ответы [ 3 ]

3 голосов
/ 27 ноября 2011

Все, что вы делаете, нехорошо.Сложно понять, с чего начать, поэтому позвольте мне начать с конца и представить «Правильный путь»:

typedef std::unique_ptr<Square> square_ptr;

void createSquares(std::vector<square_ptr> & v)
{
  v.emplace_back(new PropertySquare1(1,"purple",120));
  v.emplace_back(new PropertySquare1(2,"green",370));
  // ...
}

int main()
{
  std::vector<square_ptr> allSquares;
  createSquares(allSquares);

  for (const auto & p : allSquares)
    std::cout << "ID is: " << p->getID() << std::endl;
}

Теперь, чтобы разобрать ваши проблемы:

Прежде всего,вы храните указатели локальных переменных.Эти локальные переменные умирают в конце области действия функции, и указатели становятся висящими.Разыменование - это программная ошибка.

Во-вторых, чтобы исправить это, вы должны создать динамические объекты: squareArray[1] = new PropertySquare1(1,"purple",120); Однако это тоже проблематично.Кто-то должен будет очистить эти объекты!Вы можете перебрать массив и вызвать delete для каждого элемента.

В-третьих, 22 - это «магическое число» (потому что оно не является ни 0, ни 1).Это не должно быть жестко закодировано.Если число действительно является константой времени компиляции, назовите ее где-нибудь.

В-четвертых, в любом случае, не используйте необработанные массивы.Либо используйте std::array, если размер известен во время компиляции, либо std::vector, если размер определяется во время выполнения.

Пятый, складывая все вместе, динамический контейнер интеллектуальных указателей позаботитсяиз всех ваших забот.Это тот, который представлен в моем коде.Альтернатива, статический массив интеллектуальных указателей, вообще не будет использовать функцию инициализации, а скорее будет инициализирована прямо на месте:

const std::size_t nfuncs = 22;
std::array<square_ptr, nfuncs> allSquares {
  new PropertySquare1(1,"purple",120),
  new PropertySquare1(2,"green",370),
  // ...
};
1 голос
/ 27 ноября 2011

Ложь в том, что

PropertySquare PropertySquare1(1,"purple",120);
PropertySquare PropertySquare2(2,"purple",170);

уничтожаются в момент возврата createSquares.Таким образом, ваш массив содержит мусор при печати этих идентификаторов.

0 голосов
/ 27 ноября 2011

Поскольку переменные PropertySquare объявлены в стеке, они будут уничтожены после возврата из функции. Вы хотите объявить их в куче вместо

squareArray[1] = new PropertySquare PropertySquare1(1,"purple",120);
squareArray[2] = new PropertySquare PropertySquare1(2,"purple",170);

и удалите их в основном, позвонив delete allSquares[1] и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...