VS2015 Update 1 bug, or bad C++: Why can't a friend class access its friend's protected destructor?

删除回忆录丶 提交于 2019-12-21 08:15:35

问题


The following appears to be a pattern employed by ZeroC ICE in the code it auto-generates, which appears to me to be a way they have made singletons (not sure why) for many releases of their tool now. Various compilers have no problem with it, until I found today that Visual Studio 2015 Update 1 (VS version 14.0.24720.00, VC++ version 19.00.23506) emits an error. Before Update 1, VS2015 also had no problem with it. I'm not sure whether it's a bug (regression?) in the VS2015 C++ compiler with Update 1, or bad (not standards-conformant) C++ code that other compilers let slide.

Here is an example of the code pattern:

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

    friend class Foo_init;
};

class Foo_init {
public:
    Foo init;
};

static Foo_init staticFooInit;

VS2015 Update 1 emits these errors:

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'

I found one (as yet unanswered) ZeroC ICE forum post which seems related to this, but otherwise I haven't found out in my Google searching anything that convinces me whether this is a compiler issue or bad code. I admit I don't know ZeroC ICE very well, nor do I use C++ friend classes enough to have a deep understanding of what you can and can't do with them. I'm hoping someone more knowledgeable can shed some light on it.


回答1:


I am not 100% sure on your exact problem, but it reminds me of a problem I had a while ago, where forward declared classes would have an unexpected scope. this page cppreference class highlights the rules, that a forward-declared class has the most local scope. However, your example on my VS2015u3 does not fail either.

I think the fix is probably to forward declare the class which is a friend before the class, so that it has a well defined scope.

When you have a class such as

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

The compiler treats declaration of SomeOtherClass which is within the local scope.

This means that

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

class SomeOtherClass {
          ...
};

Declares three classes Example Example::SomeOtherClass and SomeOtherClass

Changing your example to

class Foo_init;

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

    friend Foo_init;
 };

class Foo_init {
  public:
    Foo init;
 };

 static Foo_init staticFooInit;

Should work




回答2:


You have used an identifier that starts with an underscore and then a capital letter. These names are reserved for the implementation, and using them in user code is undefined behaviour.



来源:https://stackoverflow.com/questions/34376316/vs2015-update-1-bug-or-bad-c-why-cant-a-friend-class-access-its-friends-pr

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!