class Base
{
protected:
    void func1();
};

class Derived : public Base
{
friend class Third;
};

class Third
{
     void foo()
     {
        Derive d;
        d.func1();
     }
};

我可以使用错误编译VC14(Visual Studio 2015)中的代码
但是从VC12中获取错误(Visual Studio 2013)
cannot access protected member declared in class 'Base'

谁是对的?
这种友元与继承的正确性是什么?

从MSDN的https://msdn.microsoft.com/en-us/library/465sdshe.aspxhttp://en.cppreference.com/w/cpp/language/friend看来,友元不是可传递的,不能被继承。但是,我认为此代码示例并非如此。

但是,为什么VC14不会让我出错?

如果VC14是正确的,我如何“修改”代码,以使VC12也可以?
在派生类中再次定义 protected func1()?

最佳答案

修正错字后,内联注释:

class Base
{
protected:
    void func1();   // protected access
};

class Derived : public Base
{
  // implicit protected func1, derived from Base

  // this means 'make all my protected and private names available to Third'
  friend class Third;
};

class Third
{
     void foo()
     {
        Derived d;
        // func1 is a protected name of Derived, but we are Derived's friend
        // we can therefore access every member of Derived
        d.func1();
     }
};

VC14是正确的。

VC12的可能解决方法:
class Base
{
protected:
    void func1();
};

class Derived : public Base
{
  protected:
    using Base::func1;

  private:
    friend class Third;
};


class Third
{
     void foo()
     {
        Derived d;
        d.func1();
     }
};

另一个可能的解决方法(使用基于 key 的访问)
class Third;
class Func1Key
{
  private:
    Func1Key() = default;
    friend Third;
};

class Base
{
protected:
    void func1();
};

class Derived : public Base
{
public:
  void func1(Func1Key)
  {
    Base::func1();
  }
};


class Third
{
     void foo()
     {
        Derived d;
        d.func1(Func1Key());
     }
};

08-05 16:24