0

请阅读代码以了解问题:

#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

3 回答 3

2

铿锵接受friend void ::fun(int);

void fun(int value)
{
    //starts local class definition
    class test
    {
        friend void ::fun(int);
        int x;
    public:
        test(int a)
        {
            x=a;
        }
        void display()
        {
            std::cout << "x = " << x << std::endl;
        }

    };
    //end of the definition
    test t1(value);
    t1.display();
    t1.x = 42;
    t1.display();
}

演示

而 g++ 拒绝它。

不确定哪个编译器是正确的。

于 2019-07-26T22:13:48.287 回答
2

我是否应该将有趣的功能作为本地班级的朋友(测试)

目前还不清楚您是否应该. 避免破坏私有成员提供的封装通常是一个好主意。或者相反,如果不需要封装,那么成员公开可能会更简单。但是,让我们考虑一下您是否可以...

标准说(引用最新草案):

[班级.朋友]

如果友元声明出现在本地类 ([class.local]) 中并且指定的名称是非限定名称,则在不考虑最内层非类范围之外的范围的情况下查找先前的声明。对于友元函数声明,如果没有事先声明,则程序是非良构的。...

fun如果我正确地解释了这个法律术语,就无法查找函数体之外的非限定名称 。据我所知,fun它本身的声明超出了这个范围。但是据我所知,没有什么可以阻止您重新声明该功能:

void fun(int value)
{
    void fun(int); // (re)declaration within innermost enclosing non-class scope

    class test
    {
        friend void fun(int); // the friend declaration

这似乎在 Clang 和 MSVC 中有效,但不幸的是在 GCC 中无效,它仍然不允许访问私有成员。这可能是一个 GCC 错误。

另一种选择是使用限定名称声明朋友:

class test
{
    friend void ::fun(int); // qualified name

在这种情况下,上述限制将不适用。不幸的是,GCC 也不接受这一点,并且没有本地重新声明会产生诊断:

错误:没有事先本地声明的本地类中的朋友声明“void fun(int)”

这看起来像一个单独的错误,它再现了是否将声明::fun或任何其他合格的函数名称作为朋友。我发现了一个现有的错误报告:https ://gcc.gnu.org/bugzilla/show_bug.cgi?id=69410

于 2019-07-26T22:32:00.127 回答
0

首先声明函数

void fun(int);

然后在课堂上:

public:
friend void ::fun(int  );
于 2019-07-26T22:19:17.013 回答