Ale*_*der 1 c++ friend-function
/** module.h */
#pragma once
class A {
friend void helpers::logValue(const A &);
int _val;
public:
A() {}
};
namespace helpers {
static void logValue(const A &a) {
std::cout << a._val; // <== ERROR: '_val' is not accessible
}
}
Run Code Online (Sandbox Code Playgroud)
如何在另一个命名空间中声明友元函数?
要想找到解决办法,就必须逆向思考。
我们希望它能与班级成员_val一起使用。privateA
namespace helpers {
static void logValue(const A &a) {
std::cout << a._val;
}
}
Run Code Online (Sandbox Code Playgroud)
步骤 1 要使上面的函数定义起作用,必须有A编译器可见的类的前面定义,并且该类定义必须指定helpers::logValue()(具有适当的签名,即返回类型和参数)是friend. 所以在上面的定义之前helpers::logValue()我们必须放置;
class A {
friend void helpers::logValue(const A &);
int _val;
};
Run Code Online (Sandbox Code Playgroud)
步骤 2为了使friend步骤 1 中的声明有效,编译器必须了解helpers::logValue(). 这需要编译器可见的命名空间声明区域,该区域声明具有相同签名的helpers函数,并且必须位于 的定义之前。因此,在定义 class 之前,我们必须做类似的事情;logValue()AA
namespace helpers{
static void logValue(const A &a);
}
Run Code Online (Sandbox Code Playgroud)
步骤 3helpers::logValue()如果没有可见类的声明, 编译器将因该声明而阻塞A。我们已经有了一个类定义(在步骤 1 中创建),因此我们无法创建另一个类定义(这会打破单一定义规则)。但是我们可以在步骤 2 中的代码之前添加一个声明。
class A;
Run Code Online (Sandbox Code Playgroud)
将这些步骤放在一起,我们将步骤中的代码以相反的顺序放在一起(即首先放置步骤 3 中的代码,然后放置步骤 3 中的代码,依此类推)。然后我们得到
// Step 3
class A;
// Below Step 3 comes code from Step 2
namespace helpers{
static void logValue(const A &a); // works since A is declared
}
// Below Step 2 comes code from Step 1
class A {
friend void helpers::logValue(const A &); // works since helpers::logValue() is declared
int _val;
};
// And now we come to the function definition we want to have work
namespace helpers {
static void logValue(const A &a) {
std::cout << a._val;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
344 次 |
| 最近记录: |