我目前正在学习c ++,现在正在研究继承。 我必须制作一个常规问题类以及一个派生类,该派生类是一个数字问题和多项选择问题。我在代码中提出问题,然后将其一一显示给用户。然后,用户回答问题,程序应检查答案是否正确。
#include <iostream>
#include <string>
using namespace std;
class Question {
protected:
string text;
string answer;
string input;
public:
Question(string inText, string inAnswer) {
text = inText;
answer = inAnswer;
}
Question() {
text = "blank question";
answer = " ";
}
void setQuestion(string txt) {
text = txt;
}
void setAnswer(string answr){
answer = answr;
}
void userAnswer(string ans) {
input = ans;
}
string getAnswer() {
return answer;
}
string getQuestion() {
return text;
}
void displayQuestion() {
cout << getQuestion() << endl;
}
void isCorrect() {
cout << "default function" << endl;
if (input.compare(answer) == 0)
cout << "True" << endl;
else
cout << "False" << endl;
}
};
class NumericQuestion : public Question {
protected:
double ans;
double inp;
public:
NumericQuestion(string inText, double inAns) {
text = inText;
ans = inAns;
}
void userAnswer(string ans) {
inp = stod(ans);
}
void isCorrect() {
cout << "numeric function" << endl;
if (inp == ans)
cout << "True" << endl;
else if ((inp - ans) <= 0.01)
cout << "False" << endl;
else
cout << "False" << endl;
}
};
class MultipleChoice : public Question {
protected:
string qA, qB, qC, qD;
public:
MultipleChoice(string inText, string qA, string aB, string qC, string qD, char inAnswer) {
text = inText;
answer = inAnswer;
}
void displayQuestion() {
cout << text << endl;
cout << "a) " << qA << " " << "b) " << qB << endl;
cout << "c) " << qC << " " << "d) " << qD << endl;
}
};
int main() {
string ans;
Question q1("whats 2+2", "four");
NumericQuestion q2("2+2", 4);
MultipleChoice q3("The Right Answer is C", "answer A", "thisisB", "thats C", "Wrong", 'c');
Question arr[] = { q1,q2,q3};
for (int i = 0; i < 3; i++) {
arr[i].displayQuestion();
cin >> ans;
arr[i].userAnswer(ans);
arr[i].isCorrect();
}
getchar();
return 0;
}
不使用NumericQuestion类的成员函数isCorrect()和MultipleChoice类的displayQuestion(),而是使用Question类的成员函数,这导致我的代码出现逻辑错误。
答案 0 :(得分:2)
当您执行// Created
// modifid: Created
// MySubclass Created
// MySubclass modifid: MySubclass Created
时将Question
的子类按值分配给Question
的数组时,您就是slicing objects。这意味着,即使您的某些派生Question arr[] = { q1, q2, q3 };
对象具有基类所没有的额外成员,它们也会因分配到数组中而被截断。另一个问题是,由于Question
被声明为包含简单的arr
对象,因此编译器将假定像Question
这样的调用将始终引用{{ 1}},而不是派生方法。这有几处要解决的问题。
设置可覆盖的功能virtual:
arr[i].isCorrect();
和override在子类中:
Question::isCorrect()
最后,通过存储指向您的class Question {
...
virtual void isCorrect() {
cout << "default function" << endl;
if (input.compare(answer) == 0)
cout << "True" << endl;
else
cout << "False" << endl;
}
的基类指针来避免切片。在这里,我使用std::shared_ptr来避免手动内存管理的麻烦。还出现了ranged-for loop:
class NumericQuestion : public Question {
...
void isCorrect() override {
cout << "numeric function" << endl;
if (inp == ans)
cout << "True" << endl;
else if ((inp - ans) <= 0.01)
cout << "False" << endl;
else
cout << "False" << endl;
}
答案 1 :(得分:0)
这里有两个问题。
1)基于最后的for
循环,您需要将一些函数声明为displayQuestion()
,例如userAnswer()
,isCorrect()
和virtual
。
2)其次,将您的arr
声明更改为Question *arr[] = {&q1, &q2, &q3};
。
答案 2 :(得分:0)
您需要在基类中将userAnswer
,displayQuestion
和isCorrect
设置为虚拟。
您还需要将问题存储为指针(还有其他选项),以防止切片。就个人而言,我发现这样更容易解决问题:
Question* arr[] = {&q1,&q2,&q3};
...
arr[i]->displayQuestion();
(您需要更改所有用法或使用arr [i]来使用箭头)