友元函数的单独声明
Separate declaration for friend function
我正在读C++初级读本。上面写着:
朋友声明仅指定访问权限。这不是对作用如果我们希望类的用户能够调用friend函数,那么我们还必须将函数与友元声明分开声明。为了使类的用户可以看到一个朋友,我们通常声明每个朋友(在类之外)在与类本身相同的头中
小心代码中的箭头。它在上面提到的文本中提出了我的问题。
header.h
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
#include <string>
using namespace std;
class Husband{
friend void change_salary(int changed_salary, Husband &ob);
public:
Husband() {}
Husband(unsigned new_salary) : salary{ new_salary } {}
private:
int salary;
};
//void change_salary(int changed_salary, Husband &ob); <----Code Compiles without even this declaration
#endif
main.cpp
#include "header.h"
void change_salary(int changed_salary, Husband &ob)
{
cout << "salary increased by 1000";
ob.salary = changed_salary;
}
int main()
{
Husband hs1{ 3000 };
change_salary(4000, hs1); // <---- Able to use function without explicit declaration outside of class in header
return 0;
}
如果在声明后在声明的同一文件中使用函数,则头文件中不需要原型,这就是您在main.cpp中所做的。
在头文件中放入原型有助于其他文件中的代码,或者在同一文件中但更高的文件中找到函数。在头文件中创建原型通常是一种很好的做法,以使API对人类读者清晰可见。但在这里的情况下,它并不是严格要求编译的。
友元函数声明是类设计的一部分。如果没有在类标头(或某些包含的标头)中声明函数,则您的设计是不完整的(强制用户实现该函数,或为某些用户实现打开大门,或导致违反一个定义规则(ODR))。
在定义使用它的main()
之前,您已经提供了change_salary
的定义,因此该函数始终可见,没有任何问题。但假设您将定义移动到main()
的定义之下(或移动到一个单独的.cpp文件)。
int main()
{
Husband hs1{ 3000 };
change_salary(4000, hs1);
}
void change_salary(int changed_salary, Husband &ob)
{
cout << "salary increased by 1000";
ob.salary = changed_salary;
}
即使在这种情况下,代码也将继续编译,因为change_salary
将通过依赖于参数的名称查找找到(因为第二个参数的类型为Husband&
)。
现在,让我们尝试通过在main()
中形成指向change_salary
的指针来显式引用它。
void (*p)(int, Husband&) = &change_salary;
这将无法编译,因为ADL在这种情况下不适用,并且change_salary
的定义对main()
不可见。
但是,如果取消注释头中change_salary
的声明,则代码将进行编译。这大概就是书中所说的让类用户看到朋友的意思。
- 为什么要将函数声明和定义放在单独的文件中
- 智能指针可以单独向前声明和初始化吗?
- 使用模板参数还包括 constexpr 成员函数enable_if单独定义和声明模板成员函数
- C++ 在具有单独标头的类中声明互斥锁
- 在 h 和 cpp 文件中单独声明和实现模板有时有效,有时会出现链接器错误
- 单独的类声明和方法定义文件问题
- 最终说明符对单独的声明和定义无效
- C++17 单独的显式方法模板实例化声明和定义
- 在C++中,如何在没有新元素且不单独声明单个元素的情况下创建"std::initializer_list<base *>"?
- 将全局声明为类声明语句的一部分与使用单独的语句声明全局之间是否有区别
- 如何将__DATE__和__TIME__宏拆分为变量声明的单独组件
- 从单独的文件转发模板函数的声明
- 单独的地图声明和初始化
- C++-模板类中模板函数的单独声明/定义
- 单独声明和初始化结构
- 友元函数的单独声明
- 有没有办法在单独的 .h 和 .cpp 文件中定义在命名空间中声明的函数
- 在单独的头文件 (C++) 中声明的命名空间中定义函数
- 是否可以在标头中声明 constexpr 类并在单独的.cpp文件中定义它
- 可以单独声明函数数组的元素