访问者界面的私有继承如何允许可访问对象访问访问私有访问实现?

时间:2012-08-20 23:32:48

标签: c++ inheritance private visitor-pattern

以下代码显示了一个私有继承自接口的接口,该接口访问私有函数而不授予调用对象友谊。我对此感到困惑,但无法真正看到编译器可以提出哪些更好的解决方案(代码编译和运行)。为什么这样做?

#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 A\n";
    }

    virtual void Visit(const VisitableB& b)
    {
        std::cout << "I saw B\n";
    }
};

int main(int argc, char* argv[])
{
VisitableA a;
VisitableB b;

PrivateVisitor p_a(a);
PrivateVisitor p_b(b);
} 

3 个答案:

答案 0 :(得分:4)

只在编译时检查访问说明符,并在那里检查应用它们的对象的静态类型。

PrivateVisitor内部构造函数中,*this对象已投放到IVisitor。在这种情况下,继承的类型并不重要,因为我们在PrivateVisitor类型中,因此我们拥有完全访问权限。

该对象在IVisitable对象(VisitableAVisitableB)内使用,并调用Visit成员函数。虽然对象的动态类型为PrivateVisitor,但静态类型为IVisitor(引用的类型为IVisitor&)。对IVisitor类检查访问说明符,其中Visit重载都是 public ,因此编译器接受该调用。

最终覆盖中函数私有的事实并不重要,因为访问是通过基类执行的,其中函数是 public

答案 1 :(得分:1)

这里重要的私人是这一个:

PrivateVisitor : private IVisitor

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

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

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

答案 2 :(得分:0)

private属于类范围,而不是对象范围。