【问题标题】:Method of base class getting called基类被调用的方法
【发布时间】:2021-10-22 10:02:36
【问题描述】:

我有以下代码:

#include<iostream>
using namespace std;

struct Base{
    void f(int x){
        cout<<"B";
    }
};
struct Derived: public Base {
    virtual void f(double x){
        cout<<"D";
    }
};

int main(){
Derived d;
int x = 5;
d.f(x);
Base *pb = &d;
pb->f(x);

}

它输出:DB
即使 pb 存储指向派生类的指针。为什么会调用
Base 类的方法?

【问题讨论】:

  • 您在基类方法中缺少virtual。事后您不能使方法成为虚拟方法;从一开始就必须是这样。

标签: c++ derived-class


【解决方案1】:

声明Derived::f virtual 不会使Base::f 成为虚拟,因此当您在指向Base 的指针上调用f 时,会调用Base::f

您应该在Base 中声明方法virtual。然后在Derived 中也将是virtual,你不需要在那里重复virtual。在Derived 中,您应该像这样使用override 说明符:

struct Base{
    virtual void f(int x){
        cout<<"B";
    }
};
struct Derived: public Base {
    void f(double x) override {
        cout<<"D";
    }
};

override 说明符有助于在方法实际上不是 override 继承方法时捕获错误。例如,对于上述情况,您将收到以下错误:

source>:10:10: error: 'void Derived::f(double)' marked 'override', but does not override
   10 |     void f(double x) override {
      |          ^

要覆盖时,参数类型必须匹配。

此代码打印预期的DD

#include <iostream>

struct Base {
    virtual void f(int x){
        std::cout << "B";
    }
};
struct Derived: public Base {
    void f(int x) override {
        std::cout << "D";
    }
};

请注意,如果您不使用override,那么此类错误可能会被忽视。当类定义如下:

struct Base{
    virtual void f(int x){
        std::cout<<"B";
    }
};
struct Derived: public Base {
    void f(double x) {
        std::cout<<"D";
    }
};

那么Derived::f 不会覆盖Base::f。它只是隐藏它,输出仍然是DB

Live Demo

【讨论】:

    【解决方案2】:

    由于您调用派生类的函数,它首先打印 D,然后打印 B,因为您只是调用基类的函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      • 2011-12-13
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      相关资源
      最近更新 更多