C++ 知识总结 P02:修饰
const
常量
使用宏 define
定义常量是常见的行为,在C++中还可以使用 const
关键字来实现常量的定义。
const double PI = 3.1415926535;
在类中使用常量,为了避免每个实例都产生一个常量,可以使用
static const double PI = 3.1415926535
但是在函数中定义的常量,即使重复调用函数,也不会发生浪费空间的问题。
常引用、常指针
在某些情况下,如在函数参数传递中,为避免使用引用、指针修改指向的变量,可使用如下形式的 const 。此时虽然指向的对象可能是非 const 的,但是无法通过 const 引用或 const 指针修改。
void f(const double& t);
void f(const double* p);
另外,如果目的是防止指针本身被修改,可以使用 double* const p
的形式。(引用没有这种问题,因为引用无法被修改。)
const
修饰的函数返回值
const
修饰下的函数返回值,可以防止该值被修改,但是接收该函数返回值的变量也必须有 const
属性。
const int f() {}
const int a = f();
const
修饰的成员函数
被 const
修饰的成员函数,不修改实例的成员变量。另外,如果一个对象实例化为一个常量对象,只能调用它的常成员函数。
class TypeSample {
void member() const {}
}
static
静态全局变量与静态局部变量
使用 static
修饰全局变量,与无 static
修饰的全局变量功能相同,区别为被 static
修饰后的全局变量只能在本文件中使用,在其他文件中无法使用。
使用 static
修饰函数内的局部变量,可以使该变量在函数运行结束时不被销毁,可以利用静态局部变量实现多次函数调用间的信息传递。需要强调的是,static
并不改变局部变量的作用域,也就是说在函数外部是无法访问静态局部变量的。
静态函数
在函数的声明前加上 static
修饰,作用与静态全局变量相同,使该函数只能在本文件中使用,在其他文件中无法使用。
静态成员变量与静态成员函数
使用 static
修饰的类成员变量,与普通的成员变量的区别是:普通成员变量是属于实例的,但是静态成员变量是属于类的,是类的所以实例所共有的。可以用来存放类的常量,以及仅与类本身相关的属性。
同样的,静态成员函数是属于类的,与普通的成员函数的区别是:普通成员函数都隐含了 this
指针,该指针指向实例本身,用来访问实例的成员变量和成员函数,但 this
指针不是指向类的,故静态成员函数没有 this
指针。这种区别造成了静态成员函数只能访问静态成员变量,也只能调用静态成员函数,但普通成员函数没有这种限制;另外可以使用 class_name::static_func()
的方式直接调用静态成员函数。
extern
使用外部变量
如果需要在某个工程文件中使用其它文件中定义的变量,可以使用extern指定。在需要使用外部变量的地方,放置一个 extern
修饰的变量声明即可。
#include "other.h"
extern int param; // 此变量在 other.h 中有定义
使用 C 的代码
extern
的另一个使用方法是在 C++ 中使用 C 的代码。在需要使用 C 的地方,使用 extern "C"
告知编译器。
extern "C" {
#include "c_code.h"
}
// 如果只想使用其中的一个函数
extern "C" {
int c_function(int);
}
constexpr
const
关键字并没有明确说明是在编译期间为常量还是在运行期间为常量,constexpr
告知编译器该语句或函数在编译期间就是常量,也就是说这些语句或函数在编译期间就可以计算出来。constexpr
比 const
更为严格,但是能够让编译器对代码进行更多的优化,在能使用 constexpr
的情况下推荐使用 constexpr
代替 const
。
auto 与 decltype()
auto
关键字用于声明变量时自动推导变量的类型,适合冗长的变量类型,过多的使用 auto
会造成代码可读性下降,另外某些情况下 auto
可能存在歧义,为后续代码带来隐患。
decltype()
也是用于推导变量的类型,用于已经存在的变量。
auto iter = vec.begin();
using Iter = decltype(iter);