为什么允许通过基类的指针调用派生类的私有虚方法? [英] Why is it allowed to call derived class' private virtual method via pointer of base class?

查看:144
本文介绍了为什么允许通过基类的指针调用派生类的私有虚方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

# include <iostream>
using namespace std;

class A
{
    public:
    virtual void f()
    {
        cout << "A::f()" << endl;
    }
};
class B:public A
{
    private:
    virtual void f()
    {
        cout << "B::f()" << endl;
    }
};
int main()
{
    A *ptr = new B;
    ptr->f();
    return 0;
}

此代码可以正常工作,并打印B :: f我知道它是如何工作的,但为什么这个代码允许?

This code works correctly and prints B::f(). I know how it works, but why is this code allowed?

推荐答案

访问控制在编译时执行,而不是运行时。一般来说,调用 f()是为了知道 ptr 指向的对象的运行时类型, ,所以没有检查派生类的访问说明符。这是允许调用的原因。

Access control is performed at compile time, not runtime. There's no way in general for the call to f() to know the runtime type of the object pointed to by ptr, so there's no check on the derived class's access specifiers. That's why the call is permitted.

至于为什么B类允许使用私有函数覆盖 - 我不确定。当然,B违反了它从A的继承隐含的接口,但一般来说,C ++语言并不总是强制执行接口的继承,所以事实上它是Just Plain Wrong并不意味着C ++会阻止你。

As for why class B is permitted to override using a private function at all - I'm not sure. Certainly B violates the interface implied by its inheritance from A, but in general the C++ language doesn't always enforce inheritance of interface, so the fact that it's Just Plain Wrong doesn't mean C++ will stop you.

所以我猜想这个类B可能有一些用例 - 替换仍然使用动态多态性,但是静态B不是A的替代(例如,可以有模板调用 f ,这将使用A作为参数,但不是B作为参数)。可能有些情况下,这正是你想要的。当然,这可能只是一些其他考虑的意想不到的后果。

So I'd guess that there's probably some use case for this class B - substitution still works with dynamic polymorphism, but statically B is not a substitute for A (e.g. there can be templates that call f, that would work with A as argument but not with B as argument). There may be situations where that's exactly what you want. Of course it could just be an unintended consequence of some other consideration.

这篇关于为什么允许通过基类的指针调用派生类的私有虚方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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