Лучший способ создать n объектов в конструкторе другого класса? - PullRequest
1 голос
/ 16 марта 2019

Я хотел создать переменное количество объектов Treasure при создании сундука.Это решение, которое я придумал.Чтобы создать массив из n Treasures, позже нужно будет разбирать его по мере необходимости.Возможности для совершенствования?

Chest::Chest (int n) {

Treasure * tArr = new Treasure[n];

}

Каждое сокровище имеет уникальный идентификатор, а затем анализируется на карте, отображая int ID в Treasure.

1 Ответ

1 голос
/ 16 марта 2019

Улучшение уровня 0: не теряйте созданные вами объекты

Ваша переменная tArr является локальным объектом конструктора и будет потеряна после завершения построения, что приведет к утечкам памяти.

Так что если вы хотите, чтобы этот код был полезным, вам нужно сделать tArr переменной-членом и избегать ее переопределения в конструкторе.

Chest::Chest (int n) {
    tArr = new Treasure[n];    // assuming Treasure *tArr is a class variable
}

Уровень 1 улучшения: правило 3

Первым улучшением будет реализация правила 3 . В противном случае вы быстро столкнетесь с неприятными проблемами, если, например, случайно скопируете Chest.

Улучшение уровня 2: забудьте о массивах и используйте векторы

Массивы - это средневековые времена для C ++. Используйте vector вместо:

class Chest {
    std::vector<Treasure> tArr;     // naming could be discussed...
    ...
}; 

Chest::Chest (int n) : tArr(n) {    // construct the vector with n elements
               // now do whatever you want with these elements
}

Теперь классная вещь с вектором состоит в том, что они могут расти динамически. Таким образом, вы можете начать с пустого вектора и добавить новые сокровища, используя push_back():

Treasure x(...); // create a cool treasure not just default initialized 
tArr.push_back(x);  // add it at the end of the vector

Это может позволить вам, например, в конструкторе добавлять случайные сокровища, если однородные сокровища слишком скучны.

Но вы также можете resize() передать его в произвольное значение:

tArr.resize(tArr.size()*2);   // two times more treasures !!!  

Уровень 3 улучшения: используйте карту

Следующее намерение не совсем ясно:

Каждое сокровище имеет уникальный идентификатор, а затем анализируется на карте, составляя карту int ID для Сокровища.

Предполагая, что идентификатор является последовательным и локальным по отношению к Chest, вектор - это все, что вам нужно: индекс будет идентификатором.

Если, однако, идентификатор не является последовательным или не локальным для Сундука, вас может заинтересовать карта , которая является своего рода ассоциативным массивом:

std::map<int, Treasure> myMap;  // maps an int ID to a Treasure. 

Проблема в том, что вы не можете просто создать карту с n элементами в ней: вам нужно добавить элементы один за другим:

myMap[id] = Treasure(...);      // changes the element with id, or creates it

Сектор намного проще. Так что переходите на карту, только если она действительно оправдана.

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