请阅读代码以了解问题:
#include <iostream>
void fun(int value)
{
//starts local class definition
class test
{
int x;
public:
test(int a) : x(a) {}
void display() const
{
std::cout << "x = " << x << std::endl;
}
};
//end of the definition
test t1(value);
t1.display();
//if we write the statement t1.x=100; here .It will give us an error
//because we can not access the private members from the enclosing function
//now what should I do if I want to access the private members of the test class from fun function
}
int main()
{
fun(5);
}
我应该把这个有趣的函数作为本地类的朋友(测试)吗?我在阅读一本书,据说我们可以通过将封闭函数声明为friend
来实现这一点。现在我的问题是,我不知道如何使封闭函数成为局部类的朋友。请告诉我,我该怎么做。
4条答案
按热度按时间czq61nw11#
我应该把这个有趣的函数作为本地类的朋友吗(测试)
不清楚你是否应该……避免破坏私有成员提供的封装通常是一个好主意。或者相反,如果不需要封装,那么成员是公共的可能会更简单。但让我们考虑一下你是否可以...
标准说(引用最新草案):
[同学.朋友]
如果一个友元声明出现在局部类([class.local])中,并且指定的名称是一个非限定名称,则查找前面的声明**,而不考虑最内层非类作用域之外的作用域**。对于友元函数声明,如果没有事先声明,则程序是病态的。...
如果我正确地解释了这个法律术语,那么在
fun
的函数体之外,没有任何非限定名称可以被查找。据我所知,fun
的声明本身不在这个范围之内。然而,据我所知,没有什么可以阻止你重新声明这个函数:这在Clang和MSVC中似乎可以工作,但不幸的是在GCC中不行,GCC仍然不允许访问私有成员。这可能是一个GCC bug。
另一种选择是用限定名声明朋友:
在这种情况下,上述限制将不适用。不幸的是,GCC也不接受这一点,并且在没有本地重新声明的情况下会产生一个诊断:
错误:友元声明'void fun(int)'在局部类中没有预先的局部声明
这看起来像是一个单独的bug,无论声明
::fun
还是任何其他限定函数名作为友元,它都会重现。我发现了一个现有的bugreport:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69410h79rfbju2#
限定调用
friend void ::fun(int);
是一种方法:Demo
请注意,一些旧版本的g++拒绝了它。
iq3niunx3#
首先声明函数
然后在课堂上:
mpbci0fu4#
请注意,这个bug现在已经在GCC中修复,并向后移植到版本10及以上。