11

以下似乎是 ZeroC ICE 在其自动生成的代码中使用的模式,在我看来,这似乎是他们现在为他们的工具的许多版本制作单例的一种方式(不知道为什么)。各种编译器都没问题,直到今天发现Visual Studio 2015 Update 1(VS版本14.0.24720.00,VC++版本19.00.23506)报错。在Update 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;

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'

我发现了一篇(尚未得到答复)ZeroC ICE 论坛帖子,似乎与此相关,但除此之外,我在 Google 搜索中没有发现任何可以说服我这是编译器问题还是错误代码的内容。我承认我不太了解 ZeroC ICE,我也没有使用 C++ 朋友类来深入了解你可以用它们做什么和不能做什么。我希望有更多知识的人可以对此有所了解。

4

2 回答 2

1

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

我认为修复可能是在类之前转发声明作为朋友的类,以便它具有明确定义的范围。

当你有一个类如

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

编译器将其声明视为SomeOtherClass在本地范围内。

这意味着

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

class SomeOtherClass {
          ...
};

声明三个类Example Example::SomeOtherClassSomeOtherClass

将您的示例更改为

class Foo_init;

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

    friend Foo_init;
 };

class Foo_init {
  public:
    Foo init;
 };

 static Foo_init staticFooInit;

应该管用

于 2018-05-13T08:56:09.637 回答
-7

您使用了以下划线开头的标识符,然后是大写字母。这些名称是为实现保留的,在用户代码中使用它们是未定义的行为。

于 2015-12-19T23:06:27.587 回答