代码之家  ›  专栏  ›  技术社区  ›  jbcoe

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

  •  1
  • jbcoe  · 技术社区  · 13 年前

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

    #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 回复  |  直到 13 年前
        1
  •  4
  •   David Rodríguez - dribeas    13 年前

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

    在…内 PrivateVisitor 构造函数 *this 对象被广播到 IVisitor 在这种情况下,继承的类型并不重要,因为我们在 私人访问者 类型,因此我们可以完全访问。

    该对象用于 IVisitable 对象( VisitableA VisitableB )以及 Visit 调用成员函数。而 动态 对象的类型为 私人访问者 这个 静止的 类型为 IV视察员 (参考为类型 IVisitor& )。对照访问说明符进行检查 IV视察员 类,其中 参观 过载是 平民的 ,因此编译器接受调用。

    事实上,函数是 私有的 在最后一个overrider中并不重要,因为访问是通过基类执行的,函数在基类中 平民的

        2
  •  1
  •   Sjoerd    13 年前

    这里最重要的是这个:

    PrivateVisitor : private IVisitor
    

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

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

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

        3
  •  0
  •   Keith Nicholas    13 年前

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