VS2015更新1错误,或错误的C++:为什么朋友类不能访问其朋友的受保护的析构函数?

Ric*_*ers 11 c++ ice

以下似乎是ZeroC ICE在其自动生成的代码中使用的模式,在我看来,这是他们现在为他们的工具的许多版本制作单例(不确定原因)的方式.各种编译器都没有问题,直到我今天发现Visual Studio 2015 Update 1(VS版本14.0.24720.00,VC++版本19.00.23506)发出错误.在更新1之前,VS2015也没有问题.我不确定这是一个带有Update 1的VS2015 C++编译器中的错误(回归?),还是其他编译器允许滑动的错误(不符合标准的)C++代码.

以下是代码模式的示例:

class Foo {
protected:
    virtual ~Foo() {}

    friend class Foo_init;
};

class Foo_init {
public:
    Foo init;
};

static Foo_init staticFooInit;
Run Code Online (Sandbox Code Playgroud)

VS2015 Update 1会发出以下错误:

example.cpp(13): error C2248: 'Foo::~Foo': cannot access protected member declared in class 'Foo'
example.cpp(3): note: see declaration of 'Foo::~Foo'
example.cpp(1): note: see declaration of 'Foo'
Run Code Online (Sandbox Code Playgroud)

我找到了一个(尚未回答)ZeroC ICE论坛帖子似乎与此相关,但是否则我没有在我的Google搜索中发现任何让我信服这是否是编译器问题或错误代码的信息.我承认我不太了解ZeroC ICE,也没有足够的C++朋友课程来深入了解你能做什么和不能做什么.我希望有更多知识渊博的人可以对此有所了解.

mks*_*eve 1

我不是 100% 确定你的确切问题,但它让我想起了我不久前遇到的一个问题,其中前向声明的类将具有意外的范围。此页cppreference 类突出显示了前向声明的类具有最本地范围的规则。但是,您在我的 VS2015u3 上的示例也没有失败。

我认为解决方法可能是在类之前转发声明作为友元的类,以便它具有明确定义的范围。

当你有这样的课程时

class Example {
     int someFunction( class SomeOtherClass & param );
};
Run Code Online (Sandbox Code Playgroud)

编译器将其声明视为SomeOtherClass局部范围内的声明。

这意味着

class Example {
     int someFunction( class SomeOtherClass & param );
};

class SomeOtherClass {
          ...
};
Run Code Online (Sandbox Code Playgroud)

声明三个类Example Example::SomeOtherClassSomeOtherClass

将您的示例更改为

class Foo_init;

class Foo {
  protected:
    virtual ~Foo() {}

    friend Foo_init;
 };

class Foo_init {
  public:
    Foo init;
 };

 static Foo_init staticFooInit;
Run Code Online (Sandbox Code Playgroud)

应该管用