C/C++中的关键字如下:
下面我们主要介绍一些比较陌生的关键字,一些常见的关键字这里就不再赘述了。
1、asm
asm 是一个语句的分隔符,不能单独出现,必须接汇编指令。一组被大括号包含的指令或一对空括号。示例如下:
_asm
{
mov al,2
mov dx,0xD007
out al,dx
}
也可以在每个汇编指令前加_asm:
_asm mov al,2
_asm mov dx,0xD007
_asm out al,dx
2、catch、throw、try
用于异常处理。try 用来标识可能出现的异常代码段,catch可以捕获异常,异常由throw抛出。throw 必须在 try 代码块中,后边跟的值决定抛出异常的类型。示例如下:
try
{
// 可能出异常的程序
throw ... // 掏出异常
}
catch(表达式)
{
}
C++ 中的异常处理机制只能处理由 throw 捕获的异常,没有捕获的将被忽略。使用try{ } catch() { }
语句来捕获异常,把可能发生异常的代码放在try{ }
语句块中,后面跟若干个catch() { }
语句负责处理具体的异常类型,这样一组有 try 块和不少于一个的 catch 块就构成了一级异常捕获。
3、auto
auto关键字会根据初始值自动推断变量的数据类型。但不是每个编译器都支持auto。示例如下:
auto x = 7; // 使用整数7对变量x进行初始化,可推断x为int型。
auto y=1.234; // 使用浮点数1.234对变量y进行初始化,可推断y为double型。
4、*_cast
即 const_cast、dynamic_cast、reinterpret_cast、static_cast。
C++类型风格的类型转换符。const_cast删除const变量的属性,方便赋值;dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用;reinterpret_cast将一种类型转换为另一种不同的类型;static_cast用于静态转换,任何转换都可以用它,但他不能用于两个不相关的类型转换。
注:具体使用可以参考我的另一篇博客:C++中的四种强制类型转换符详解
5、typeid
从名字直观看来,该关键字应该是获取语言元素的类型ID。有时候代码可能需要获取某个变量或者类型的名字,这时候使用typeid就比较合适。示例如下:
typeid(int).name(); // 获取int类型名,结果为“int”
typeid(1)!= typeid(1.0); // 比较表达式类型,结果为true
6、typename
typename在函数模板和类模板声明中使用。一般模板声明中,使用class关键字指定类型参数,后来C++支持使用typename代替class关键字。这里typename和class没有任何区别。示例如下:
template<class T, class Y>;
// 可以用下面替代
template<typename T, typename Y>
7、mutable
Mutable的含义是可变的,它和const关键字是相对的。我们知道类的常成员函数在语义上是不允许修改类的成员变量的,但是有时候可能根据代码的需要并不是这么绝对。那么就可以使用mutable声明一个类的成员变量,它告诉编译器类的常成员函数可以修改这个变量。示例如下:
class MyClass
{
mutable int member;
void constFun()const
{
member=0;
}
};
如果不使用mutable修饰member定义,就会编译报错。
8、explicit
explicit的含义是显式的,该关键字的作用就是阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。
在C++中,如下声明是合法的:
class String
{
String(const char* p);
};
String s1 = "hello"; // 合法
上例中,String s1 = "hello"
会执行隐式转换,等价于String s1 = String("hello")
。为了避免这种情况的发生,可以在函数声明前面加上explicit,禁止隐式类型转换。示例如下:
class String
{
explicit String(const char* p);
};
//String s1 = "hello"; // 非法报错
9、export
使用该关键字可实现模板函数的外部调用。对模板类型,可以在头文件中声明模板类和模板函数;在代码文件中,使用关键字export来定义具体的模板类对象和模板函数;然后在其他用户代码文件中,包含声明头文件后,就可以使用该这些对象和函数。
10、operator
和操作符连用,指定一个重载了的操作符函数,比如,operator ++。示例如下:
class Time
{
public:
// 重载后缀递增运算符( ++ )
// 后置递增就是增加当前对象的值,并且返回增加值之前的该对象
Time operator ++(int)
{
Time origin = *this; // 保存原先未改变的对象
second++;
return origin;
}
private:
int second;
};
11、volatile
volatile 是易变的意思,被其修饰的变量,编译器不会对其进行优化。所以每次用到它的时候都是直接从对应的内存当中提取,而不会利用 cache(缓存)或寄存器中的原有数值,以适应它的未知何时会发生的变化。它一般用来修饰多线程间被多个任务共享的变量和并行设备硬件寄存器等。例如:
int a = 0;
int b = a;
int c = a + 1;
编译器极可能把 a 放在寄存器中,供 b,c 的计算使用。更有甚者,编译器确定 a 的值是0,会直接计算出 b=0,c=1。如果在实际运行中 a 的值被其他线程修改,这么做就改变了代码的语意。为了消除这种问题,使用 volatile 关键字取消优化,让编译器每次访问 a 的时候都需要读内存,而不是读寄存器中可能被修改的值。
参考: