26. 扩展的inline说明符
C++中的inline
说明符通常用于提示编译器将函数展开(即在调用点替换为函数体),以避免函数调用的开销。但随着C++标准的发展,inline
说明符不仅仅局限于此。尤其是在C++11及以后的标准中,inline
的用途有所扩展,涵盖了更多与链接和符号可见性相关的功能。
- 在类中声明并定义
inline
静态变量(C++17引入)
// MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <iostream>
class MyClass {
public:
inline static int staticVar = 10; // 使用inline定义静态变量
static void printStaticVar() {
std::cout << "staticVar: " << staticVar << std::endl;
}
};
#endif // MYCLASS_H
27. 常量表达式
在 C++ 中,常量表达式(constexpr
)是用于在编译期求值的表达式。它在程序的编译过程中进行计算,这可以提高代码性能,减少运行时的计算负担。C++11 引入了 constexpr
关键字,并在 C++14、C++17 和 C++20 中对其进行了进一步改进。
- 常量表达式是一种编译期常量,即编译器能够在编译阶段对表达式进行求值并得到结果,而不是在运行时求值。
- 提高编译期求值:通过将部分计算移到编译期,减少运行时开销。
- 常量化表达式:在编译期进行验证和强制检查,避免运行时出错。
constexpr
可以用于:- 变量
- 函数
- 构造函数
constexpr
变量必须在编译期可以确定它的值。因此,只能用常量表达式来初始化它。- 常量表达式函数是可以在编译期求值的函数,返回值可以用于初始化
constexpr
变量。
class Point {
public:
constexpr Point(double x, double y) : x_(x), y_(y) {}
constexpr double getX() const { return x_; }
constexpr double getY() const { return y_; }
private:
double x_;
double y_;
};
int main() {
constexpr Point p1(1.0, 2.0); // 编译期创建对象
constexpr double x = p1.getX(); // 编译期获取 x 坐标
}
-
constexpr
函数要求- 在 C++11 中,
constexpr
函数的主体只能包含单一的return
语句。 - 在 C++14 中,
constexpr
函数放宽了要求,可以包含更复杂的逻辑,例如循环、条件语句等。 - 在 C++20 中,
constexpr
函数可以包含几乎所有语言特性,例如try
-catch
块,但仍然要求这些代码在常量上下文中能够执行。
- 在 C++11 中,
28. 确定的表达式求值顺序(C++17)
函数参数求值顺序(未定义)
函数参数的求值顺序在 C++ 标准中通常是未定义的,即编译器可以选择以任意顺序求值函数参数。例如:
foo(bar(), baz());
后缀表达式
对于通过 .
或 ->
进行的多级函数调用,方法的调用顺序是确定的,从左到右依次执行。例如:
obj.method1(foo(), bar()).method2(baz(), qux());
在这种情况下,执行顺序为:
- 首先求值
foo()
和bar()
(顺序未定义),然后调用method1(foo(), bar())
。 - 然后求值
baz()
和qux()
(顺序未定义),再调用method2(baz(), qux())
。
因此,foo()
和 bar()
必须在 method1()
被调用之前完成,同样,baz()
和 qux()
必须在 method2()
被调用之前完成。