内联(inline)
内联变量
C++17引入了内联变量,使得变量可以在头文件中定义并在多个编译单元中使用,避免了传统的extern声明和单一cpp文件定义的限制。它的作用是方便在头文件中定义全局变量而不会引起链接错误。
// usecase1.h |
内联函数
内联函数通过inline
关键字声明,建议编译器在调用时将函数的代码插入调用点,避免函数调用时的开销。使用inline
并不强制编译器将其内联,这是一个非绑定(non-binding)的建议。
实现内联的方式
-
小函数
不仅是指这个函数代码量少,而且编译成汇编指令后也要少,代码量大或者有复杂指令的,如循环、switch等,编译器都会拒绝将其编译为内联函数。另外,析构函数一般也不建议使用内联,谁也不知道最终它会调用多少其它函数来释放资源。
-
惟一
这里的惟一指的是惟一的调用点,而不是调用一次。它其实是一个理论上的可能,实际上,很少能够做到。所以这点基本可以忽略。
类内定义的函数通常自动成为内联函数:
class Temp { |
类外定义的成员函数则需要显示声明为inline
:
inline void Temp::print_amount() { std::cout << amount << std::endl; } |
内联函数与宏的区别
-
宏:在编译前由预处理器展开,不进行类型检查,可能带来隐患和维护问题。
-
内联函数:经过编译器的类型检查,更安全,且能够继承宏的一些优点,如减少函数调用开销。
|
虽然内联函数可以减少函数调用的开销,但它会增加代码体积,尤其在多次调用时。过度使用内联可能导致缓存失效,反而影响性能。因此,内联函数通常适用于小型且高频调用的函数。
友元(friend)
友元函数
友元函数是定义在类外部的普通函数,但它需要在类的内部通过 friend
关键字进行声明。友元函数虽然不属于类的成员,但它可以访问类的私有和受保护成员。友元函数的存在主要是为了在保持类的封装性的同时,提供一定的灵活性。
友元函数的特点:
-
可以访问私有成员:友元函数可以访问类中的私有成员(
private
和protected
)。 -
声明时使用
friend
关键字:友元函数需要在类的内部用friend
关键字声明,函数的定义则可以在类外进行。 -
不是类的成员函数:虽然友元函数能够访问类的私有成员,但它不属于该类的成员函数,也不影响类的结构。
友元函数的常见用途:
-
运算符重载:尤其是在重载
<<
和>>
这样的运算符时,由于ostream
或istream
对象通常在函数调用时位于左操作数位置,需要友元函数来实现操作。 -
跨类访问:有时需要在非成员函数中访问类的私有成员,而不想公开这些成员给所有的外部函数。
|
<<
和 >>
这类运算符重载时,通常第一个操作数是 ostream
或 istream
对象,而不是类的实例,因此无法将运算符重载定义为成员函数。这时候可以通过友元函数来实现。
友元函数声明在类中,可以访问类的私有数据成员 _year
、_month
和 _day
,从而对类进行输出和输入操作。
友元类
友元类是指一个类被声明为另一个类的友元,从而可以访问该类的私有和受保护成员。友元类的所有成员函数都可以访问被友元的类的私有成员。友元类是一种更广泛的友元机制,它允许两个类紧密合作。
友元类的特点:
-
单向访问:友元类可以访问被声明为友元的类的私有成员,但这种访问权不会自动逆转(即被声明为友元的类不能访问友元类的私有成员)。
-
不具备传递性:如果类 A 是类 B 的友元,类 C 是类 A 的友元,这并不意味着类 C 也能访问类 B 的私有成员。
-
友元关系不能继承:友元关系仅限于声明的类,子类不能继承父类的友元关系。
友元类的常见用途:
-
紧密协作的类:当两个类需要紧密合作并共享数据时,友元类机制可以允许一个类访问另一个类的私有成员,而不需要公开这些成员。
-
实现复杂逻辑:某些情况下,一个类的实现依赖于另一个类的内部数据,友元类可以帮助简化这些情况。
|
Time
类将 Date
类声明为友元类,因此 Date
可以访问 Time
的私有成员 _hour
、_minute
和 _second
。
SetTime
函数通过 Date
类修改了 Time
类的私有数据,ShowTime
函数则显示了这些私有数据。
Reference
[1] C++之内联(inline):https://blog.csdn.net/haokan123456789/article/details/138469420
[2] 【C++】友元函数和友元类(作用及优缺点):https://blog.csdn.net/Jacky_Feng/article/details/109533248