c++函数重新定义(代码不工作 - 逻辑错误)

标签 c++ function class inheritance overriding

我目前正在学习 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 类的成员函数,这导致我的代码出现逻辑错误。

最佳答案

你是 slicing objects当您按值将 Question 的子类分配给 Question 数组时 当您执行 Question arr[] = { q1, q2, q3 };。这意味着即使您的某些派生 Question 对象具有基类没有的额外成员,它们也会被数组中的赋值截断。另一个问题是,因为 arr 被声明为包含简单明了的 Question 对象,所以编译器会假定像 arr[i].isCorrect(); 这样的调用。 始终 引用Question::isCorrect(),而不是派生方法。这里有一些问题需要解决。

创建可重写的函数 virtual :

class Question {
    ...
    virtual void isCorrect() {
        cout << "default function" << endl;
        if (input.compare(answer) == 0)
            cout << "True" << endl;
        else
            cout << "False" << endl;
    }

override它们在子类中:

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;
    }

最后,通过存储指向您的问题 的基类指针来避免切片。在这里,我使用 std::shared_ptr避免手动内存管理的麻烦。同时出现的是 ranged-for loop :

auto q1 = std::make_shared<Question>("whats 2+2", "four");
auto q2 = std::make_shared<NumericQuestion> q2("2+2", 4);

auto q3 = std::make_shared<MultipleChoice>("The Right Answer is C", "answer A", "thisisB", "thats C", "Wrong", 'c');

// even though q1...q3 are shared_ptrs to derived classes, they can be safely cast to shared_ptrs to the base class
std::vector<std::shared_ptr<Question>> questions { q1, q2, q3 };

for (const auto& question: questions) {
    question->displayQuestion();
    cin >> ans;
    question->userAnswer(ans);
    question->isCorrect();
}

关于c++函数重新定义(代码不工作 - 逻辑错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51753711/

相关文章:

c++ - 带有数组的 boost::ptr_vector:我可以确定它的析构函数调用 delete[] 而不是 delete 吗?

c++ - 多线程与 std::atomic<>

JavaScript - 如果函数作为参数传递,是否可以在计算函数之前将其作为字符串返回?

list - Haskell:调用其他函数+递归

python : putting functions into classes

c++ - 静态重载与 SFINAE 结合使用

c++ - C++ 中的 set 和 unordered_set 有什么区别?

javascript - 访问 .innerHTML 中的不同对象问题

php - 类PHP中的奇怪错误对象

python - Python 在实例化新类时返回什么?