代码改变世界

c++ 中的生僻关键字

2011-06-03 10:29  Rollen Holt  阅读(320)  评论(0编辑  收藏  举报

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值
           type_info类提供了public虚析构函数,以使用户能够用其作为基类。它的默认构造函数和拷贝构造函数及赋值操作符都定义为private,所以不能定义或复制type_info类型的对象。程序中创建type_info对象的唯一方法是使用typeid操作符(由此可见,如果把typeid看作函数的话,其应该是type_info的友元)。type_info的name成员函数返回C-style的字符串,用来表示相应的类型名,但务必注意这个返回的类型名与程序中使用的相应类型名并不一定一致(往往如此 ),这是由实现所决定的,标准只要求实现为每个类型返回唯一的字符串。

         注意:当把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);
}

4.const_cast

           const_cast把常量强制转换为非常量,或者把volatile转换成非volatile类型的。eg.

const int a = 10;
//int &b = a;// 这样写是错误的,提示错误的因为a是常量,b是非常了,之间不可以相互转换的
int &b = const_cast<int &>(a);//这样是正确的,因为const_cast<int&>(a)返回的是一个非量的地址了。

5.volatile    

       volatile英文翻译过来的意思是“易变的,反复无常的”,是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。

6.explicit

      explicit意思是显式的。只能用在构造函数前面,并且一般是单参数的构造函数,或者有多个参数但仅有一个参数没有默认值.被explicit修饰的构造函数表明是显式的,既然有显式的,那么肯定有隐式的了,先说一说隐式的构造函数。

class Test
{
public:
Test(int i){
}
};

如果我们这样用,Test t(3) ;t = 10;那么在t=10这个语句中,就用到了隐式转换,编译器会这样解释,Test temp(10),t = temp,也就是说其中生成了一个临时变量。这就是隐式转换。如果我们有这样的一个函数 int f(const Test &t),调用的时候f(3),一不小心我们还会以为,f里的参数是int型的呢,为了防止这种隐式转换,就用到了explicit,在构造函数前面加上explicit就可以防止这种隐式转换。

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.