【问题标题】:How do I return a class object to an empty state such that it may be reused?如何将类对象返回到空状态以便可以重用?
【发布时间】:2019-10-04 08:03:36
【问题描述】:

我正在编写一个入门级脚本来模拟疾病传播。我正在尝试编写它,以便我可以运行多次试验并每次输出结果。该脚本使用一个 Person 类和一个 Population 类,后者由一个人员向量组成。每个试验返回相同的结果(单独测试时,它们从相同的输入返回不同的结果)。我想我需要在每次试验中清除我的人口对象,但我不太确定如何。

我想我需要一个析构函数,但我不确定语法。在线资源对于我的技能水平来说太先进了,或者当我尝试复制它们的语法时给了我错误消息。

class Person {
  private:  // Person constructor
    int status; bool infected;
  public:
    Person(){
      status = 0; infected = false;
    };

    string status_string(){  // Outputs status of each person with a symbol as a string
      };

     void update_per(){ // Updates status of each person if they are sic
     };

     void infect(int n){ // Infects person if they are susceptible (not recovered or vaccinated)
     };  
     void vaccinate(){ // Changes status of person to being vaccinated
     };
     bool is_stable(){ // Determines if person has recovered from infection
     };
     int get_status() { // Returns status of person
      };

};

class Population {    //Create population class
  private:      //declare private variable npeople
    int npeople;
    vector<Person> population;   //create a vector of Persons named population with size npeople
  public:
    Population(int n){
      srand(time(NULL));
      npeople = n;
      population = vector<Person>(n);
    };
    ~Population()  //DESTRUCTOR
      {
        delete[] population;
      };
    void random_infection(int days){ //method to randomly infect one person
    };

    int count_infected() {    //method to count the number of people infected
    };

    void update_pop(int ncontacts, float contagion, int days) { // Updates the status of each person in population, also simulates spread of disease through contact
    };
    void print_status(){ // Output status of each person in population
    };

    void vacc_pop(float prob){ // Vaccinates a set number of people in the population
    };
};

int main() {
  ofstream popsizeresults;
  int size; // Asks user for size of population
  int numtrials; // Asks user for number of trials
  for (int jjjj=1; jjjj<=numtrials; jjjj++){
    int maxsick = 0;
    int day = 0;
    Population population(size); // Create population
    population.vacc_pop(0.5); // Vaccinate population
    population.random_infection(5); // Infect one random person in population

int step = 1;
    for ( ; ; step++){
      // Output status of each person in population
      cout<<"In step "<<step<< " #sick: "<<population.count_infected()<<" : ";
      population.print_status();
      cout<<endl;
      // If no people are sick, then the disease has run its course
      if(population.count_infected() == 0)
        break;
      // Update the status of each person and simulate spread of disease
      population.update_pop(size*0.25,0.9,5);
    if (population.count_infected() > maxsick){
      maxsick = population.count_infected();
      day = step;
    }    
    }
  popsizeresults.open("disease10.txt", ios::app);
  popsizeresults << jjjj << "," << step << "," << maxsick << "," << day << "\n";
  popsizeresults.close();
  //population.~Population(); //call destructor
  return 0;
  }
}

在我添加析构函数(不起作用)之前,disease10.txt 上的输出会为每次试验产生不同的结果,但每次试验的结果相同。当它一次测试一个试验时(对于相同的输入),它会产生不同的结果(这是目标)。我不确定析构函数是否真的是这里的答案,我对 C++ 很陌生。无论哪种方式,我都不确定如何为每个试验复制不同的结果。

【问题讨论】:

  • 析构函数肯定是不正确的。如此处所写,这是编译器错误,不是吗? /example.cpp: In destructor 'Population::~Population()': ./example.cpp:45:18: error: type 'class std::vector&lt;Person&gt;' argument given to 'delete', expected pointer 45 | delete[] population; |
  • 目前肯定是编译器错误,我将其保留以显示我的尝试。析构函数是否可能不是我正在寻找的答案?
  • 不清楚您在寻找什么。如果您想将population 重置为新构建的状态,您可以执行population = Population(n); 将其设置为全新的n-person 人口。
  • Population 应在每次循环 for (int jjjj=1; jjjj&lt;=numtrials; jjjj++){ 执行时重置。但问题是你把return 0 放在这个循环中,所以它只执行一次。无论如何,你的代码有更多的问题,例如很多变量在没有事先初始化的情况下使用,如int sizeint numtrials 等。

标签: c++ class object destructor


【解决方案1】:

现在我明白了你在追求什么,这是一个非常精简的人口重置演示。

请参阅 cmets 中的编号注释以改进样式等。

#include <vector>
#include <iostream>

// a very basic Person for exposition
class Person 
{
  public:

    Person() {    };
};

// Population cut down to the bare minimum
class Population 
{
  private:
    // note 1: no need to store npeople. a vector has a size(). Why store the same thing twice
    // note 2: never use `using namespace std;` at global scope. Spell out std:: explicitly 

    std::vector<Person> population;

  public:

    // note 3: number of people can never be negative, so why give ourselves the choice? make it unsiged
    Population(unsigned n)
    // note 4: use list initialisation in constructors
    : population(n)
    {
    };

    // note 5: no need for destructors. google "rule of none", "rule of 5", "rule of 3". Prefer rule of none


    // answer: 
    // a specific function to reset the population
    void reset(unsigned n)
    {
        // destroy old people
        population.clear();

        // make new people
        population.resize(n);
    }

    // note 6: allows us to print a representation of a population for exposition
    friend std::ostream& operator<<(std::ostream& os, Population const& pop)
    {
        for (Person const& p : pop.population)
        {
            os << '.';
        }
        os << "(" << pop.population.size() << " people)";
        return os;
    }
};

int main() 
{
    Population population = Population(10);
    std::cout << population << '\n';

    // note 6: reset the population
    population.reset(5);
    std::cout << population << '\n';
}

预期输出:

..........(10 people)
.....(5 people)

现场演示: https://coliru.stacked-crooked.com/a/02868f61f6a3da4d

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    相关资源
    最近更新 更多