1.typeid.
typeid表达式形如:typeid(expr)这里expr是任意表达式或者类型名。如果表达式的类型是类类型且至少包含有一个虚函数,则typeid操作符返回表达式的动态类型,需要在运行时计算(编译器需要/GR支持);否则,typeid操作符返回表达式的静态类型,在编译时就可以计算。
typeid操作符的返回结果是名为type_info的标准库类型的对象的引用(在头文件typeinfo中定义)。标准并没有确切定义type_info,它的确切定义编译器相关的,但是标准却规定了其实现必需提供如下四种操作:
t1 == t2 | 如果两个对象t1和t2类型相同,则返回true;否则返回false |
t1 != t2 | 如果两个对象t1和t2类型不同,则返回true;否则返回false |
t.name() | 返回类型的C-style字符串,类型名字用系统相关的方法产生 |
t1.before(t2) | 返回指出t1是否出现在t2之前的bool值 |
注意:当把typeid作用于指针的解引用*p时,若指针p为0,则:如果p指向的类型是带虚函数的类类型,则typeid(*p)在运行时抛出一个bad_typeid异常;否则,typeid(*p)的结果与p的值是不相关的,在编译时就可以确定。typeid表达式的这点性质与sizeof表达式相似但又有区别,sizeof一定是在编译时进行计算,也就是说,其只考虑表达式的静态类型,与表达式的动态类型无关(即使有虚函数存在)。
2.mutable:
这个是相对与const而言的,如果一个变量被声明为const,一般情况下那么这个变量的内容是不可更改的,但是用mutable修饰后,那么这个变量的const的属性就没有,和普通的变量就没有什么区别了,可以在任何地方被修改。
class Test2
{
public:
Test2():a(30)
{
}
void OutPut(int i) const;//这样在output函数里面就不可修改a,和b的值了
private :
const int a;//声明为const的成员变量,必须要在构造函数中初始化这个变量,并且只能通过初始化列表的方式
int b;//mutable int b;被mutable修饰后,在output中可以被修改
};
void Test2::OutPut(int i) const
{
cout<<a<<endl;
b = 3;//Error因为被const修饰的成员函数是不可以改变类的成员变量的,但是如果在类的成员变量前用mutable修饰,那么这个变量就可以被修改。
}
int main( void )
{
Test2 t;
t.OutPut(3);
}
const_cast把常量强制转换为非常量,或者把volatile转换成非volatile类型的。
const int a = 10; //int &b = a;// 这样写是错误的,提示错误的因为a是常量,b是非常了,之间不可以相互转换的 int &b = const_cast<int &>(a);//这样是正确的,因为const_cast<int&>(a)返回的是一个非量的地址了。
volatile英文翻译过来的意思是“易变的,反复无常的”,是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。
6.explicit
explicit意思是显式的。只能用在构造函数前面,并且一般是单参数的构造函数,或者有多个参数但仅有一个参数没有默认值.被explicit修饰的构造函数表明是显式的,既然有显式的,那么肯定有隐式的了,先说一说隐式的构造函数。
class Test { public: Test(int i) {} };
7.__super
Allows you to explicitly state that you are calling a base-class implementation for a function that you are overriding.
__super can only appear within the body of a member function.
__super cannot be used with a using declaration.