explicit
export
mutable
volatile
using namespace
auto
asm register
static_cast dynamic_cast reinterpret_cast const_cast
this inlinetry catch throw
typedefstatic
1、explicit
这个关键字对于好的代码是必要的。
使用explicit关键字,将构造函数声明为显式构造函数,以防止隐式的类型转换。
explicit只对一个实参的构造函数有效。需要多个实参的构造函数不能用于执行隐式转换,所以无须指定为explicit。
只能在类中声明的时候使用explicit关键字,在类外不能使用。
除非有明显的理由需要定义隐式转换,否则,单参数构造函数应该声明为explicit,可以避免错误。
在C++标准库中,接受一个容量参数的vector构造函数,是explicit的。
2、export
export关键字是一个很少被使用的关键字。它用于模板函数。在模板函数的定义时,加上export关键字,用于指明给定的定义可能会需要在其它文件中产生实例化,避免编译器为每个文件中的模板产生实例。
在一个程序中,一个模板只能定义为export一次。
一般是在函数模板的定义时使用。对于类模板,在类实现文件中使用。
export关键字不是一个好的关键字,应当避免使用。在最新的C++11标准中,已经取消了该关键字。
3、mutable
mutable是可变的意思,用于声明类的数据成员,称为可变数据成员。使用mutable修饰的类数据成员,即使在const成员函数内部,也可修改其值。
4、volatile
该单词的意思是易变的,不稳定的。它的作用是,作为指令关键字,确保本指令不会被编译器优化而省略,要求每次直接读值。比如:
用途:
1
2
3
4
|
int
square(
volatile
int
*ptr)
{
return
((*ptr) * (*ptr));
}
|
4
5
6
7
|
int
square(
volatile
int
*ptr)
{
int
a,b;
a = *ptr;
b = *ptr;
return
a*b;
}
|
1
2
3
4
5
6
|
long
square(
volatile
int
*ptr)
{
int
a;
a = *ptr;
return
a*a;
}
|
4
5
6
7
|
int
square(
volatile
int
*ptr)
{
int
a,b;
a = *ptr;
b = *ptr;
return
a*b;
}
|
1
2
3
4
5
6
|
long
square(
volatile
int
*ptr)
{
int
a;
a = *ptr;
return
a*a;
}
典型的例子
这个语句用来测试空循环的速度的
但是 编译器肯定要把它优化掉,根本就不执行
如果你写成
它就会执行了
|
5、using namespace
所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
namespace其作用是可以避免导致全局命名冲突问题。功能相似于Java中的import。
1
|
std::cout<<std::hex<<3.4<<std::endl;
|
1
|
cout<<usingstd::hex<<3.4<<endl;
|
1
2
3
4
|
#include<iostream>
#include<sstream>
#include<string>
using
namespace
std
|
6、auto
1
|
auto
x=5.2;
//这里的x被auto推断为double类型
|
1
2
3
4
5
6
|
map<
int
,
int
>m;
for
(
auto
it=m.begin();
//这里it被auto推断为map<int,int>::iterator类型
it!=m.end();++it)
{
//....
}
|
7、register
asm和register关键字一般很少使用。
register关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,加快其存储速度,以提高效率。注意是尽可能,不是绝对。一个CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多register 变量,它不能全部把这些变量放入寄存器。
使用register 修饰符的注意点
但是使用register修饰符有几点限制。
首先,register变量必须是能被CPU所接受的类型。这通常意味着register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。不过,有些机器的寄存器也能存放浮点数。
其次,因为register变量可能不存放在内存中,所以不能用“&”来获取register变量的地址。
由于寄存器的数量有限,而且某些寄存器只能接受特定类型的数据(如指针和浮点数),因此真正起作用的register修饰符的数目和类型都依赖于运行程序的机器,而任何多余的register修饰符都将被编译程序所忽略。
在某些情况下,把变量保存在寄存器中反而会降低程序的运行速度。因为被占用的寄存器不能再用于其它目的;或者变量被使用的次数不够多,不足以装入和存储变量所带来的额外开销。
8、asm
__asm关键字启动内联汇编并且能写在任何c/c++合法语句之处.它不能单独出现.它必须接汇编指令、一组被大括号包含的指令或一对空括号.术语“__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
因为__asm关键字是一个语句分隔符,你也可以将汇编指令放在同一行: __asm mov al, 2 __asm mov dx, 0xD007 __asm out al, dx
以上三个的例子产生相同的代码,但是第一种风格(把__asm块用括号括起来)有一些优势。括号可以清晰的将C或C++代码和汇编代码分开,并且避免了不必要的重复__asm关键字。括号也能避免模糊性。如果你想在__asm块的同一行放置一个C或C++语句,你必须将块用括号括起来。没有括号,编译器不能告诉汇编代码在哪里停止而C或C++代码在哪里开始。最后,因为在括号的文字有和原始MASM一样的格式,你能轻松的从一个已有的MASM源文件里剪切和黏贴文字到文件来。不同于C和C++的括号,包含__asm块的括号对变量的作用域并没有效果。你也能嵌套__asm块,嵌套对变量作用域也没有效果。