【问题标题】:compiler error on calling derived class function using base class pointer which is not in base class使用不在基类中的基类指针调用派生类函数时出现编译器错误
【发布时间】:2021-09-04 19:36:38
【问题描述】:

我正在学习 C++ 虚函数。

#include<iostream>

class Base{
    virtual void fun(){
        std::cout<<"Base\n";
    }
};

class Derived:public Base{
    void fun(){
        std::cout<<"Derived\n";
    }
    virtual void fun1(){
        std::cout<<"Derived 1 \n";
    }
};

int main(){
    Base* b=new Derived();
    b->fun1();
}

我写了这段代码,但它没有编译。根据动态多态的概念,如果我们创建一个指向派生类的基类指针,那么我们可以调用派生类的函数,对吧?使用 Derived 类的虚指针,我们可以调用虚表中的 fun1 函数,对吧?

但是为什么这里不编译呢?

【问题讨论】:

  • 多态性不是这样工作的。我在 Base 类中看不到 fun1() 函数。其次,您的Base 类缺少虚拟析构函数,因此如果您尝试发出delete b;,您将调用未定义的行为。
  • 多态性是关于用一种类型替换另一种类型。即,能够将Derived 替换为Base,但是使用BaseBase 没有 fun1,没有什么可以替代的。

标签: c++ virtual-functions


【解决方案1】:

您不能从类外部调用任何BaseDerived 成员函数,因为这些函数是private。你需要让他们public

另一个问题: fun1 不是Base 的成员,因此您不能通过基类指针调用fun1

两种可能的解决方案:

  • Base 中声明一个纯virtual void fun1() = 0Demo
  • 在调用之前将b 转换为Derived*static_cast&lt;Derived*&gt;(b)-&gt;fun1();Demo

您的程序也在泄漏内存。你需要delete b;,当你这样做时,它现在只会调用Base 析构函数(结果是未定义的行为),因为你的Base 没有virtual 析构函数。

virtual ~Base() = default;

然后在main:

   // ...
   delete b;

Demo 使用智能指针std::unique_ptr&lt;Base&gt; 而不必手动delete

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多