【问题标题】:Inheritance Overriding继承覆盖
【发布时间】:2019-06-29 19:05:46
【问题描述】:

我有一个关于继承覆盖期间的早期/晚期绑定的问题。

因此,我将介绍 C++ 的 OOP 基础知识,并阅读到如果您不在基类 virtual 上声明函数,则无法覆盖它。但是我有以下代码,看起来我的编译器无论如何都会为我覆盖它。

#include <iostream>

using namespace std;

class Book{
public:
    string title;
    int number;

    Book(){
    }

    Book(string title){
        cout << "book " << title << " created" << endl;
    }

    void setNumber(int num){
        number = num + 7;
    }

    ~Book(){
        cout << "book " << title << " destroyed:";
    }
};

class Magazine: public Book {
public:

    void setNumber(int num){
    number = num;
    }
};

int main()
{
    Magazine mag;
    mag.setNumber(4);
    cout << mag.title << endl;
    cout << "the number you are looking for is: " << mag.number << endl;
}

我的编译器的输出是 4,但根据我读过的内容,c++ 具有早期绑定,如果函数未在基类中声明为虚拟,则不应覆盖它,因此应输出 num + 7 如基类所述。我只是得到了不正确的资源吗?或者这可能是我的编译器中的错误/异常?

感谢大家的帮助

【问题讨论】:

    标签: c++ oop virtual


    【解决方案1】:

    您可以“覆盖”非虚拟函数,但实现不会动态绑定,而是静态绑定。您将意识到与多态性的区别:

    Book* mag = new Magazine();
    mag->setNumber(4);
    cout << mag->title << endl;
    cout << "the number you are looking for is: " << mag->number << endl;
    

    这将调用Book-implementations,而当您将成员函数声明为虚拟时,它将动态绑定到 Magazines 实现。

    【讨论】:

    • +1 但我认为提及override 并显示“固定”代码示例将有助于完成此答案。
    【解决方案2】:

    您没有覆盖您的功能。你所做的就是重新定义

    如果你想确保你重写了函数,在你的函数声明之后放置override关键字,看看你是否被重写了。

    例子:

    void suspicious() override; -(C++11 特性)

    另外很高兴知道,如果你重新定义一个函数“使用哪个函数(类型检查)”发生在编译时,如果你用相同的名字声明你的函数虚拟它发生在运行时通过虚拟表机制。

    【讨论】:

      【解决方案3】:

      virtual 关键字实际上只有在处理多态性时才会发挥作用。只有当你有指针/引用时才会发生这种情况。

      如果您改为执行以下操作:

      int main()
      {
          Magazine mag;
          Book *b = &mag;
          b->setNumber(4);
          cout << b->title << endl;
          cout << "the number you are looking for is: " << b->number << endl;
      }
      

      您会看到我们最终调用了Book::setNumber(),尽管我们实际上指向的是Magazine

      如果您将setNumber 声明为virtual 函数并运行上述代码,您将使用动态函数绑定。因此,由于我们有一个Book 指针,因此程序不会立即调用Book::setNumber(),而是动态检查b 实际指向的内容。因为它实际上是一个Magazine 对象,所以我们将调用Magazine::setNumber()。这就是多态的魔力。

      【讨论】:

      • "只有当你有指针时才会发生这种情况" - 或引用。
      【解决方案4】:

      与其试图解释,我建议你尝试以下实验:

      Book &book = Mag;
      book.setNumber(4);
      cout << mag.number << endl;
      

      然后用Book::setNumber 声明virtual 重复此操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-10
        • 1970-01-01
        • 1970-01-01
        • 2017-09-21
        • 2012-11-20
        • 2017-09-30
        相关资源
        最近更新 更多