访问接口的私有继承如何允许可访问对象访问访问私有访问实现

How can private inheritance from a visitor interface allow a visitable object to access visit private visit implementations?

本文关键字:访问 许可 实现 对象 何允 继承 接口      更新时间:2023-10-16

下面的代码显示了一个类,该类从一个接口私有继承,该接口在不授予调用对象友谊的情况下访问其私有函数。我对此感到困惑,但真的看不出编译器能想出什么更好的解决方案(代码编译和运行)。为什么这样做?

#include <iostream>
class IVisitor;
class IVisitable
{
public:
    virtual void Accept(IVisitor& visitor) const = 0;
};
class VisitableA;
class VisitableB;
class IVisitor
{
public:
    virtual void Visit(const VisitableA& a) = 0;
    virtual void Visit(const VisitableB& b) = 0;
};
class VisitableA : public IVisitable
{
public:
    virtual void Accept(IVisitor& visitor) const
    {
        visitor.Visit(*this);
    }
};
class VisitableB : public IVisitable
{
public:
    virtual void Accept(IVisitor& visitor) const
    {
        visitor.Visit(*this);
    }
};
class PrivateVisitor : private IVisitor
{
public:
    PrivateVisitor(IVisitable& v)
    {
        v.Accept(*this);    
    }
private:
    virtual void Visit(const VisitableA& a)
    {
        std::cout << "I saw An";
    }
    virtual void Visit(const VisitableB& b)
    {
        std::cout << "I saw Bn";
    }
};
int main(int argc, char* argv[])
{
VisitableA a;
VisitableB b;
PrivateVisitor p_a(a);
PrivateVisitor p_b(b);
} 

访问说明符仅在编译时进行检查,并在应用它们的对象的静态类型上进行检查。

PrivateVisitor构造函数中,*this对象被强制转换为IVisitor。在这种情况下,继承的类型无关紧要,因为我们属于PrivateVisitor类型,所以我们有完全的访问权限。

该对象在IVisitable对象(VisitableAVisitableB)内部使用,并调用Visit成员函数。当对象的动态类型为PrivateVisitor时,静态型为IVisitor(引用为IVisitor&型)。根据IVisitor类检查访问说明符,其中两个Visit重载都是公共,因此编译器接受调用。

函数在最终重写器中是private这一事实并不重要,因为访问是通过基类执行的,其中函数是public

这里最重要的是这个:

PrivateVisitor : private IVisitor

幸运的是,PrivateVisitor被强制转换为IVisitor的唯一地方是构造函数:

PrivateVisitor::PrivateVisitor(IVisitable& v)
{
    v.Accept(*this);
}

构造函数可以访问类的私有基。

private在类范围内,而不是对象范围内。