C++ 关键字
static关键字
- 修饰局部变量
static修饰局部变量时,使得被修饰的变量成为静态变量,存储在静态区。存储在静态区的数据生命周期和村工序相同,在main函数之前初始化,在程序退出时销毁。(无论时局部静态还是全局静态) - 修饰全局变量
全局变量本来就存储在静态区,因此static并不能改变其存储位置。但是,static限制了其链接属性。被static修饰的全局变量只能被包含该定义的文件访问(即改变了作用域) - 修饰函数
static修饰函数使得函数只能在包含该函数定义的文件中被调用。对于静态函数,生命和定义需要放在同一个文件夹中。 - 修饰成员变量
用static修饰的数据成员使其成为类的全局变量,会被类的所有对象共享,包括派生类的对象,所有的对象都只维持同一个示例。因此,static成员必须在类外进行初始化(初始化格式: int base::var = 10;),而不能在构造函数内进行初始化,不过也可以用const修饰static数据成员在类内初始化。 - 修饰成员函数
用static修饰成员函数,使这个类只存在这一份函数,所有对象共享该函数,不含this指针,因而只能访问类的static成员变量。静态成员是可以独立访问的,也就是说,无须创建人换个对象实例就可以访问。例如可以封装某些算法,比如数学函数,如sin,tan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好,比如定义一个数学函数类Math,调用Math::sin(3.14);还可以实现某些特殊的设计模式:如Singleton
const关键字
- 定义变量为只读变量,不可修改
- 修饰函数的参数和返回值(后者应用比较少,一般为值传递)
- constant成员函数(只需要在成员函数最后加上const,如char get() const;)可以访问const成员变量和非const成员变量,但是不能修改任何变量。在声明一个成员函数时,若该成员函数并不对数据成员进行修改操作,应尽可能将该成员函数声明为const成员函数。
- const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数,即对于class A,有const A a;那么a只能访问A的const成员函数。对于A b;b可以访问任何成员函数。
mutable关键字
在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。
typedef关键字
- 提高了可移植性
- 简单复杂的类型声明,提高编码效率
- 解释数据类型的作用
extern关键字
- 与"C"一起连用的时候,如 extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数的时候按着C的规则区翻译,而不是C++(这与C++的重载有关,C++语言支持函数重载,C语言不支持函数重载,函数被C++编译器编译后在库中的名字与C语言不同)
- 不与"C"在一起修饰变量和函数时,如exturn int g_Int;它在作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块或其他模块中使用。记住它是一个声明而不是定义!也就是说B模块(编译单元)要时引用A模块中定义的全局变量或函数时,它只要包含A模块的头文件即可,在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,它会在连接时从模块A生成的目标代码中找到此函数或变量。
explicit关键字
C++中的explicit关键字只能用于修饰只有一个参数的类构造函数,它的作用是表明该构造函数是显示的,,而非隐式的,,跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式)。explicit关键字的作用就是防止类构造函数的隐式自动转换。
class Test1{
public:
Test1(int num) {
m_num = num;
} // 普通构造函数
private:
int m_num;
};
class Test2{
public:
explicit Test2(int num) {
m_num = num;
} // 普通构造函数
private:
int m_num;
};
int main() {
Test1 t1 = 12; // 隐式调用其构造函数,成功
Test2 t2 = 12; // 编译错误,不能隐式调用其构造函数
Test2 t3(12); // 显示调用成功
return 0;
}
virtual关键字
- C++中的函数调用默认不使用动态绑定。要触发动态绑定,必须满足两个条件:
- 指定该函数为虚函数
- 通过基类类型的引用或指针调用
由此可见,virtual主要作用就是实现动态绑定
- 友元函数、构造函数、static静态函数不能用virtual修饰
- 普通成员函数、析构函数可以用virtual修饰
- 只要基类中的函数定义了virtual,集成类的该函数也具有virtual属性
- 析构函数最好写成virtual(通过虚函数表,编译器知道要去执行基类的析构函数,执行完派生类的析构函数后,按照C++的内部机制紧接着区执行基类的析构函数)
class Test1
{
public:
Test1() { printf("Test1()\n"); }
~Test1() { printf("~Test1()\n"); }
}
class Test2
{
public:
Test2() { printf("Test2()\n"); }
~Test2() { printf("~Test2()\n"); }
}
class Test3
{
public:
Test3() { printf("Test3()\n"); }
virtual ~Test3() { printf("~Test3()\n"); }
}
class Test4
{
public:
Test4() { printf("Test4()\n"); }
~Test4() { printf("~Test4()\n"); }
}
int main{
Test1 t1 = new Test2();
delete t1;
Test1 t3 = new Test3();
delete t3;
// 运行结果
/**
Test1()
Test2()
~Test1()
Test3()
Test4()
~Test4()
~Test3()
**/
}