以下似乎是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;
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 forum post,这似乎与此有关,但是我在谷歌搜索中找不到任何让我信服这是编译器问题还是错误代码的东西。我承认我不太了解ZeroC ICE,也没有足够的C ++朋友课程来深入了解你可以做什么,不能做些什么。我希望有更多知识渊博的人可以对此有所了解。
答案 0 :(得分:1)
我对你确切的问题并不是100%肯定,但它让我想起了我前一段时间遇到的问题,其中前向声明的类会有意想不到的范围。此页面cppreference class突出显示规则,即前向声明的类具有最本地范围。但是,我的VS2015u3上的示例也没有失败。
我认为修复可能是为了在类之前声明一个朋友的类,因此它具有明确定义的范围。
当你有一个类
class Example {
int someFunction( class SomeOtherClass & param );
};
编译器处理在本地范围内的SomeOtherClass
声明。
这意味着
class Example {
int someFunction( class SomeOtherClass & param );
};
class SomeOtherClass {
...
};
声明三个类Example
Example::SomeOtherClass
和SomeOtherClass
将您的示例更改为
class Foo_init;
class Foo {
protected:
virtual ~Foo() {}
friend Foo_init;
};
class Foo_init {
public:
Foo init;
};
static Foo_init staticFooInit;
应该工作
答案 1 :(得分:-6)
您使用的标识符以下划线开头,然后是大写字母。这些名称是为实现保留的,在用户代码中使用它们是未定义的行为。