派生类中的虚函数

Posted

技术标签:

【中文标题】派生类中的虚函数【英文标题】:Virtual Functions in Derived Classes 【发布时间】:2020-07-31 22:01:15 【问题描述】:

看了几个视频,终于知道虚函数调用是如何通过后期绑定处理的。

在早期绑定中,对于像 ptr->func(...) 这样的行,编译器会检查 ptr 的数据类型并在相应的类中查找 func(...) 定义。

在对虚函数进行后期绑定时,访问ptr地址,然后在对应的类中查找定义。

如果我对我刚才提到的机制是正确的,那么为什么下面的代码会产生错误?

class A
   public:
       void func()
       
;

class B: public A
    public:
       virtual void f4()
           cout<<"Cunt"<<endl;
       

;

int main()
    A* ptr;
    B obj;
    ptr=&obj;
    ptr->f4();
    return 0;

另外,为什么下面的代码会产生输出base而不是输出derived

class A
   public:
       void f4()
           cout<<"base"<<endl;
       
;

class B: public A
    public:
       virtual void f4()
           cout<<"derived"<<endl;
       

;

int main()
    A* ptr;
    B obj;
    ptr=&obj;
    ptr->f4();
    return 0;

请帮忙。我对机制有误吗?

【问题讨论】:

【参考方案1】:

A类中,函数f4也应该定义为virtual

class A 
   public:
       virtual void f4()
           std::cout << "base" << std::endl;
       
;

在您的情况下,f4 是非虚拟函数,由于非虚拟继承。 还有一件事,派生的虚函数应该标记为overridevirtual不是必须的:

class B : public A 
public:
    void f4() override 
        std::cout << "derived" << std::endl;
    
;

如果您尝试在B 中将f4 标记为override 而不首先在A 中设置virtual,您将收到编译错误:error: ‘virtual void B::f4()’ marked ‘override’, but does not override- 这意味着您不会可以使用A 类指针访问它。

旁注:阅读以下帖子:Why is "using namespace std;" considered bad practice?

【讨论】:

【参考方案2】:

在您的第一个示例中,A 没有名为 f4() 的方法,因此对 ptr-&gt;f4() 的调用无效。

在您的第二个示例中,A::f4() 未标记为 virtual,因此对 ptr-&gt;f4() 的调用不执行虚拟调度,因此调用 A::f4() 而不是 B::f4()

这两个问题的解决方法是一样的——让f4()A中是虚拟的,并拥有Boverride它,例如:

class A
   public:
       virtual void f4() 
           cout << "base" << endl;
       
;

class B: public A
    public:
       void f4() override 
           cout << "derived" << endl;
       
;

int main()
    A* ptr;
    B obj;
    ptr = &obj;
    ptr->f4();
    return 0;

【讨论】:

以上是关于派生类中的虚函数的主要内容,如果未能解决你的问题,请参考以下文章

c++中的虚函数有啥作用?

虚函数与作用域

在“函数参数”中通过const类型在派生类中使用不同函数参数的虚函数会破坏虚函数吗? [重复]

虚函数******

虚函数

c++ 虚函数和纯虚函数