【问题标题】:Two constructors (with & without parameter), no input -> run without parameter. Skipping constructors in the classes above两个构造函数(带 & 不带参数),无输入 -> 无参数运行。跳过上述类中的构造函数
【发布时间】:2018-02-21 15:43:49
【问题描述】:

现在我有一个包含多个子类的类。所有类都包含一个构造函数,要求在每个类中输入数据(它是私有的,因此每个类都要求它自己的数据)。现在,我正在研究一个需要名称的子类。如果用户按 ENTER(无输入),它将运行不带参数的类的构造函数。如果有任何输入,它将将该输入放入具有参数的类的构造函数中。

我的问题是,每当我没有输入时,它都会询问它应该提出的所有问题(来自子类之上的类),并且运行良好。但是,它会跳过名称的第一个字母。例如,我将“Jordan”写为名称,然后将其保存为“ordan”。

其次,如果我没有输入,它将使用没有参数的构造函数。它询问名称(它是由主类“主”构造器询问的。我写了名称,它跳过了子构造器的所有其他问题——这是不应该做的。

我试图在 case 'F' 中创建一个对象:like Fish f1;这行得通,但这不是我应该在这里做的(家庭作业)。会是什么?我认为可能是 cin.ignore();搞砸了,但我需要它。

我觉得很难解释,但是如果您使用下面的代码执行以下操作(在控制台中编写)。

  1. 系统会要求您写“F”来添加一条鱼,请写 F。
  2. 随便写一个名字(不为空)。
  3. 所有其他问题都将得到回答,这是不应该的。构造函数应该问问题 - 这是第一个 问题。

再一次,从新开始:

  1. 写“F”来添加一条鱼。
  2. 什么都不写,只要在询问姓名时按 Enter。
  3. 随便写一个名字。
  4. 在淡水问题上写 y 或 n,下一个问题同理。
  5. 您会看到名称的首字母已丢失。

这是代码(缩短):

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <iostream>
using namespace std;

const int STRLEN = 20;

// FUNCTIONS
bool Question(); // User input y or n, sets the correct bool value
void Answer(bool n);    // Changes true to yes, false to no

class Animal {
private:
    char name[STRLEN];

public:
    Animal() { cout << "\nAnimal name: "; cin.ignore();  cin.getline(name, STRLEN); }
    Animal(char nam[]) { strcpy(name, nam); } // Const with parameter, sent from Fish-class

    void writeName() { cout << "Name: " << name << '\n'; } 
};

class AnimalWater : public Animal {
private:
    bool freshwater;

public:
    AnimalWater() { cout << "Freshwater? (y/n): "; freshwater = Question(); }
    AnimalWater(char name[]) : Animal(name) { } // Sendes name (used by Fish) up to Animal-class
    void writeWater() { cout << "Freshwater? "; Answer(freshwater); cout << '\n'; }
};

class Fisk : public AnimalWater {
private:
    bool haveGills;

public:
    Fisk() { cout << "Does the fish have gills? (y/n): "; haveGills = Question(); }
    Fisk(char name[]) : AnimalWater(name) { } // Send the Fish name up to Animal-class
    void writeGills() { Answer(haveGills); }
};

int main() {
    char choice;

    cout << "\nWrite F to add a fish: ";
    cin >> choice; choice = toupper(choice); 

    while (choice != 'Q') {             // If not Q(uit), run
        switch (choice) {
        case 'F': {
            char fishname[STRLEN];
            cout << "Name of the fish: "; cin.ignore();
            cin.getline(fishname, STRLEN);

            if (strlen(fishname) > 0) {  // if user input > 0
                Fisk f1(fishname); // sned fishname as parameter to the Fish constructor
                f1.writeName(); f1.writeWater(); f1.writeGills();
            }
            else {  // else use the constructor without parameter
                Fisk f1; f1.writeName(); f1.writeWater(); f1.writeGills(); 
            }
            break;
        }
        }

        cout << "\n\nWhat to do? ";
        cin >> choice; choice = toupper(choice);
    }
    return 0;
}

bool Question() { 
    char answer; cin >> answer; answer = toupper(answer); 
    if (answer == 'Y') return true; 
    else return false;
}

void Answer(bool n) {
    if (n) cout << "yes";
    else cout << "no";
}

【问题讨论】:

    标签: c++ class constructor subclass


    【解决方案1】:

    出现吃掉第一个字母的问题是因为你在Animal 的构造函数中吃掉了一个字符。调用cin.ignore() 会忽略一个字符。如果您在cin &gt;&gt; 之后使用cin.getline(),这没问题,因为operator&gt;&gt;\n 留在缓冲区中,而cin.getline() 将读取空字符串。但是,在您的情况下,它不会发生。你应该到处使用cin &gt;&gt; 方法。

    此外,在大多数情况下,在模型的构造函数中从用户那里获取输入并不是一个好方法。

    【讨论】:

      猜你喜欢
      • 2011-10-08
      • 2015-02-03
      • 1970-01-01
      • 2013-11-07
      • 2018-06-03
      • 1970-01-01
      • 2011-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多