Почему моя векторная инициализация делает все объекты в моем массиве одинаковыми? - PullRequest
0 голосов
/ 03 октября 2019

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

Я попытался инициализировать конструктор класса Settler в цикле for, но это неt ничего не изменилось, кроме того, что каждый раз, когда вы запрашиваете информацию об одном из них, вы получаете различный набор поселенцев.

Конструктор поселенцев:

class Settler {
  public:
  int settlerAge;
  string settlerName;
  string settlerGender;
  string settlerWealth;

  Settler(int type, int nation, int quantity) {
    int result{};
    string givenName{};
    string surName{};
    // Latin Male First Name
    string latinMaleName[15] = {"Faustus", "Mamercus", "Mettius", "Appius", "Hostus", "Quintus", "Cossus", "Secundus", "Servius", "Gallio", "Tettienus", "Petronius", "Paesentius", "Pescunnius", "Clodius"};
    // Latin Surname
    string latinSurname[30] = {"Natalinus", "Lucilianus", "Crispian", "Laetinianus", "Falco", "Otho", "Plautius", "Pascentius", "Lepidus", "Moderatus", "Caeparius", "Caetronius", "Hostilius", "Aedinius", "Papius", "Gennadia", "Triaria", "Planta","Amantia", "Mico", "Opilio", "Augusta", "Laevina", "Longina", "Mico", "Servana", "Sicula", "Iovina", "Albana", "Concessa"};
    // Latin Female First Name
    string latinFemaleName[15] = {"Vorenia", "Tuccia", "Consentia", "Vinicia", "Aurelia", "Helvia", "Fabia", "Aemilia", "Petilia", "Cloelia", "Viducia", "Betiliena", "Sornatia", "Memmia", "Pedia"};
    // As above, so below...
    string germanMaleName[15] = {"Carsten", "Benedikt", "Emmerich", "Tillmann", "Maik", "Severin", "Adrian", "Gregor", "Ingolf", "Germund", "Adelmar", "Eckard", "Raimund", "Marwin", "Dietmar"};
    string germanSurname[30] = {"Loeb", "Spielberg", "Lindemann", "Frenz", "Buxbaum", "Macher", "Bacharach", "Homrighausen", "Faulhaber", "Herder", "Germar", "Eisen", "Hackl", "Specht", "Rossmann", "Erdmann", "Osterhaus", "Steinsaltz", "Spiegelmann", "Lindemann", "Kluckhohn", "Kuttner", "Seelmann", "Sattler", "Kautner", "Dunhaupt", "Scharf", "Preisner", "Werthner", "Breitner"};
    string germanFemaleName[15] = {"Selina", "Isabel", "Walburg", "Berta", "Kate", "Gisela", "Amelie", "Ronja", "Karin", "Lena", "Alexandra", "Sarah", "Monica", "Kai", "Nadja"};
    // NOTE: Surname is before given name in eastern nations
    string easternMaleName[15] = {"Nikki", "Moronobu", "Yaichiro", "Shuncho", "Tamasaburo", "Sekien", "Kazutoshi", "Yasuhide", "Omezo", "Kinzo", "Junji", "Utamuro", "Hisaki", "Taki", "Mitsuo"};
    string easternSurname[30] = {"Maki", "Shinohara", "Tsukino", "Ikeda", "Matsutoya", "Sakata", "Horiuchi", "Suda", "Tsuga", "Kawano", "Kanbayashi", "Kirigaya", "Sakimoto", "Urushido", "Inaba", "Tsukiyomi", "Saeki", "Soga", "Morioka", "Yamabe", "Nakajima", "Maruyama", "Suga", "Kamino", "Kawamoto", "Takanashi", "Ito", "Kuramoto", "Maeda", "Kanemaru"};
    string easternFemaleName[15] = {"Saito", "Ane", "Fuuko", "Taji", "Isoko", "Gen", "Kuwa", "Taira", "Sachi", "Uka", "Ryoko", "Hina", "Mitsu", "Asa", "Tomie"};

    // Gender Generation (Male/Female)
    result = (1 + (rand() % 2));
    if (result > 1) {
      settlerGender = "female";
    } else {
      settlerGender = "male";
    }

    // Name and Age Generation (See Arrays)
    result = (rand() % 15);
    switch(nation) {
      case 1: // Latin (Equal split of ages)
      if (settlerGender == "male") {
        givenName = latinMaleName[result];
      } else {
        givenName = latinFemaleName[result];
      }
      result = (1 + (rand() % 100));
      if (result >= 66) {
        settlerAge = (41 + (rand() % 30));
      } else if (result > 33 || result < 66) {
        settlerAge = (22 + (rand() % 41));
      } else {
        settlerAge = (1 + (rand() % 22));
      }
      result = (rand() % 30);
      surName = latinSurname[result];
      settlerName = givenName + " " + surName;
      break;
      case 2: // German (More young people)
      if (settlerGender == "male") {
        givenName = germanMaleName[result];
      } else {
        givenName = germanFemaleName[result];
      }
      result = (1 + (rand() % 100));
      if (result >= 90) {
        settlerAge = (41 + (rand() % 30));
      } else if (result > 40 || result < 90) {
        settlerAge = (22 + (rand() % 41));
      } else {
        settlerAge = (1 + (rand() % 22));
      }
      result = (rand() % 30);
      surName = germanSurname[result];
      settlerName = givenName + " " + surName;
      break;
      case 3: // Eastern (More older people)
      if (settlerGender == "male") {
        givenName = easternMaleName[result];
      } else {
        givenName = easternFemaleName[result];
      }
      result = (1 + (rand() % 100));
      if (result >= 40) {
        settlerAge = (41 + (rand() % 30));
      } else if (result > 20 || result < 40) {
        settlerAge = (22 + (rand() % 41));
      } else {
        settlerAge = (1 + (rand() % 22));
      }
      result = (rand() % 30);
      surName = easternSurname[result];
      settlerName = surName + " " + givenName;
      break;
    }

    // Wealth Generation (Poor/Decent/Rich: Based on Surname)
    switch(type){
      case 1: // Hamlet
      if (result >= 28) {
        settlerWealth = "Rich";
      } else if (result > 24 || result < 28) {
        settlerWealth = "Decent";
      } else {
        settlerWealth = "Poor";
      }
      break;
      case 2: // Village
      if (result >= 26) {
        settlerWealth = "Rich";
      } else if (result > 19 || result < 26) {
        settlerWealth = "Decent";
      } else {
        settlerWealth = "Poor";
      }
      break;
      case 3: // Town
      if (result >= 25) {
        settlerWealth = "Rich";
      } else if (result > 9 || result < 25) {
        settlerWealth = "Decent";
      } else {
        settlerWealth = "Poor";
      }
      break;
      case 4: // City
      if (result >= 20) {
        settlerWealth = "Rich";
      } else if (result > 9 || result < 20) {
        settlerWealth = "Decent";
      } else {
        settlerWealth = "Poor";
      }
      break;
    }
  }
};

Инициализация и вывод вектора:

    Settlement objSettlement(tempType,tempNation);
    int tempNum = objSettlement.settlementQuantity;
    std::vector<Settler> objSettler(objSettlement.settlementQuantity, Settler(tempType, tempNation, tempNum));
    cout << "Welcome to the " << objSettlement.settlementType << " " << objSettlement.settlementName << " in the " << objSettlement.settlementNation << " nation!\n";
    cout << "Featuring a population of " << objSettlement.settlementQuantity << " with " << objSettlement.settlementWealth << " wealth.\n\n";

    bool repeat = true;
    while (repeat == true) {
      cout << "Enter the ID of a settler you would like to read about (from 0-" << (objSettlement.settlementQuantity - 1) << ", or enter 999999 to exit): ";
      cin >> tempNum;
      cout << "\n\n";
      if (tempNum == 999999) {
        repeat = false;
      } else {
      cout << objSettler[tempNum].settlerName << ", " << objSettler[tempNum].settlerGender << ", is " << objSettler[tempNum].settlerAge << " years old and has " << objSettler[tempNum].settlerWealth << " wealth.\n\n";
      }
    }

Для контекста "objSettlement" относится к случайно сгенерированному экземпляру Settlement, а ".settlementQuantity" представляет собой целое число, представляющее население населенного пункта.

Итак, когда я создаю латинскую деревню с 30 людьми,Программа создает вектор с 30 случаями: «Фауст Криспиан, мужчина, ему 41 год и он имеет плохое богатство». независимо от того, какое число я ввожу в 0-29.

Почему моя инициализация вектора делает все объекты в моем массиве одинаковыми?

Ответы [ 2 ]

5 голосов
/ 03 октября 2019

This:

std::vector<Settler> objSettler(objSettlement.settlementQuantity, Settler(tempType, tempNation, tempNum));

создает вектор с objSettlement.settlementQuantity копиями одного и того же объекта Settler(tempType, tempNation, tempNum).

См. Эту справочную страницу для получения подробной информации окак работают различные векторные конструкторы.

Нечто подобное может быть ближе к тому, что вы хотите:

std::vector<Settler> objSettler;
for (int i = 0; i < objSettlement.settlementQuantity; ++i) {
    objSettler.emplace_back(tempType, tempNation, tempNum);
}
3 голосов
/ 03 октября 2019

Когда вы создаете вектор objSettler, вы случайным образом создаете одного Поселенца, который будет скопирован objSettlement.settlementQuantity раз. Другими словами, ваш конструктор вызывается только один раз, и экземпляры в векторе создаются из этого одного объекта-поселенца с использованием конструктора копирования по умолчанию.

См. std::vector

Для генерации n случайных поселенцев вы можете использовать std::generate_n и std::back_inserter:

std::vector<Settler> objSettler;
std::generate_n(std::back_inserter(objSettler),
                objSettlement.settlementQuantity,
                [&](){ return Settler(tempType, tempNation, tempNum); });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...