朋友应该在嵌套类中传递吗?
class private_object
{
private:
struct make_public;
friend struct make_public;
static void method1() {}
};
struct private_object::make_public
{
class nested_outer
{
void callFromOuter()
{ private_object::method1(); } // Should this be an error?
class nested_inner
{
void callFromInner()
{ private_object::method1(); } // How about this one?
};
};
};
当我试图移植一个开源项目在borland下编译时,出现了这个友谊问题。根据 parashift 和两个半相关的问题< a href="https://stackoverflow.com/questions/5013717/are-inner-classes-in-c-automatically-friends">此处 和 此处,上面的示例应该无效。
然而,在七个个不同的编译器1上进行测试后,只有 borland 和 dmc 提出了抱怨。这种行为让我感到惊讶,因为我没想到友谊会在嵌套类中传递。
因此,这提出了几个问题:
- 什么是正确的行为?我猜这是大多数编译器接受的一种。
- 如果这是正确的行为,为什么这个友谊传递性实例可以?
- 如果这是正确的,那么这也意味着标准的变化。标准中允许这样做的原因可能是什么?
- 对于拒绝此代码的编译器,适当的解决方法是什么?请记住,实际项目可能包含相当深的嵌套,因此我正在寻找半可扩展的解决方案。
<子>1。在 mingw-gcc 4.5.2、clang、borland c++ builder2007、digital mars、open watcom、visualc2010 和 comeau online 上进行了测试
class private_object
{
private:
struct make_public;
friend struct make_public;
static void method1() {}
};
struct private_object::make_public
{
class nested_outer
{
void callFromOuter()
{ private_object::method1(); } // Should this be an error?
class nested_inner
{
void callFromInner()
{ private_object::method1(); } // How about this one?
};
};
};
This friendship issue came up when I was trying to port an open source project to compile under borland. According to parashift and two semi-related questions here and here, the above example should not be valid.
However, after testing it on seven different compilers1, only borland and dmc complained. This behavior surprised me because I wasn't expecting friendship to be transitive in nested classes.
So this raises a couple of questions:
- What is the right behavior? I'm guessing it's the one accepted by most compilers.
- If this is the correct behavior, why is this instance of friendship transitivity ok?
- If this is correct then that would also imply a change in the standard. What might be the reasons for allowing this in the standard?
- For compilers that rejected this code, what would be an appropriate workaround? Keep in mind that an actual project might contain fairly deep nesting so I'm looking for a solution that's semi-scalable.
1. tested on mingw-gcc 4.5.2, clang, borland c++ builder2007, digital mars, open watcom, visualc2010 and comeau online
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 C++03 中,默认情况下,嵌套类无法访问封闭类的
private
和protected
成员(请参阅§11.8/1)。但是如果你让他们成为封闭类的朋友,那么他们就可以访问它们。但是嵌套类的嵌套类仍然不是最外层封闭类的友元,嵌套类的嵌套类不能访问最外层封闭类的私有和受保护成员;如前所述,它甚至无法访问直接封闭类的私有成员和受保护成员。你正在做的就是那样,因此这是不允许的。C++ 标准 (2003) 在 $11.8/1 [class.access.nest] 中说,
标准本身的示例:
它是 C++03 标准中的缺陷。
顺便说一句,这是 C++03 标准中的一个缺陷。由于嵌套类是成员,因此它应该有权访问私有成员和受保护成员,就像任何其他成员一样:
§9.2/1 (C++03):
请参阅此缺陷报告:
In C++03, nested class cannot access
private
andprotected
members of enclosing class by default (see §11.8/1). But if you make them friend of the enclosing classs, then they can access them. But again nested class of nested class is still not friend of the outermost enclosing class, the nested class of the nested class cannot access private and protected members of the outermost enclosing class; it cannot even access the private and protected member of the immediate enclosing class, as noted earlier. What you're doing is that, hence that is not allowed.The C++ Standard (2003) says in $11.8/1 [class.access.nest],
Example from the Standard itself:
Its a defect in the C++03 Standard.
By the way, its a defect in the C++03 Standard. Since the nested class is a member, it should have access to private and protected members, just like any other member:
§9.2/1 (C++03):
See this Defect Report :
我不知何故觉得这应该允许。虽然我不确定标准行为。有人可以指出来。
我能想到的最好的办法就是制作一个包装器:
I somehow feel that this should be allowed. Though I am not sure about the standard behavior. Someone can point out.
Best I can think of is to make a wrapper: