VC12和VC14对c++友好和继承的不同行为

Different behavior about c++ Friendship and inheritance from VC12 and VC14

本文关键字:继承 VC14 c++ VC12      更新时间:2023-10-16
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'

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

from MSDN https://msdn.microsoft.com/en-us/library/465sdshe.aspx or http://en.cppreference.com/w/cpp/language/friend看起来友谊是不可传递的,不能被继承。然而,我认为这不是这个代码示例的实际情况。

但是为什么VC14不会给我一个错误?

如果VC14是正确的,我如何"修改"代码,使VC12也可以吗?定义受保护的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();
     }
};

另一个可能的解决方案(使用基于键的访问)

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());
     }
};