使用非虚拟覆盖来隐藏虚拟函数 [英] Hide virtual function with non-virtual override

查看:146
本文介绍了使用非虚拟覆盖来隐藏虚拟函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <iostream>

using namespace std;

class A {
public:
    virtual void foo() {
        cout << "A" << endl;
    }
};

class B : public A {
public:
    void foo() {
        cout << "B" << endl;
    }
};

class C : public B {
public:
    void foo() {
        cout << "C" << endl;
    }
};

int main() {
    C c;
    B* b = &c;
    b->foo();

    return 0;
}

输出 C ,但我预计 B

我没有声明 B :: foo ()和 virtual 修饰符,因此我希望函数调用由静态类型(无多态性)确定。

I didn't declare B::foo() with the virtual modifier, so I expect the function call to be determined by the static type (no polymorphism).

为什么 C :: foo()被调用?

它可能在派生类中提供一个非虚函数,隐藏基函数中的虚函数?派生成员函数有什么签名,所以 b-> foo()调用它,而不是(b-> *& A :: foo)()

Is it possible to provide a non-virtual function in a derived class, that hides the virtual function in the base? What signature should the derived member function have so that b->foo() calls it, and not (b->*&A::foo)()

推荐答案

成员函数的虚拟继承原理是C ++标准的直接后果:

The principle of virtual inheritance of a member function is is a direct consequence of the C++ Standard:


10.3 / 2:如果虚拟成员函数vf在类Base和类Derived ,直接或间接地派生来自Base,
a成员函数vf具有相同的名称,参数类型列表,
cv-qualification和refqualifier Base :: vf is
declared,then Derived :: vf is also virtual



<因此,无论继承的级别如何,函数将在从A派生的所有类中都是虚拟的。没有必要放置关键字 virtual

这种多态方法的目标是确保您始终调用与对象的真实idendity相对应的适当函数,而不管您使用指向基础或指向对象的真实类的指针。这就是为什么你获得C!

The goal of this polymorphic approach is to ensure that you always call the appropriate function corresponding to the real idendity of your object, regardless the fact that you use a pointer to a base or a pointer to the real class of the object. This is why you obtain "C" !

这个相关的问题我解释了一个窍门,给使用多个继承在一个单一级别删除虚拟的印象。然而,它可以只做一个单一的级别(你应该做你的基本指针的类)。

In this related SO question I explain a trick to give the impression of removing virtuality at one single level, using multiple inheritance. However it can be done only for a single level (you should do it for the class of your base pointer).

*顺便说一句,你可以写 pb-> B :: foo(); *&

*By the way, you could write pb->B::foo(); no need of *&.

这篇关于使用非虚拟覆盖来隐藏虚拟函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆