复习C++中的几个不常用关键字

今天听到一个朋友来TX面试,又问到了生僻的C++关键字,那个汗,记得我那个时候面试的时候也被问到过,特总结如下:

      bad_typeid
      很生僻,基本在几年的开发中没有用过,要理解bad_typeid这个关键字,首先得看下typeid这个关键字的使用,下面是一段英文描述:

The typeid operator will accept a pointer when dereferenced evaluates to a type:typeid(*P);  
If the pointer points to a null value then the typeid operator will throw a bad_typeid exception.
      也就是说,当typeid这个操作符应用到一个空指针上的时候,会抛出一个bad_typeid异常,bad_typeid本质是一个类,定义在typeinfo文件中。见下面的例子,来之msdn,注意至少使用vs2003进行测试,vc6没有实现:

  1. // expre_bad_typeid.cpp   
  2. // compile with: /EHsc /GR   
  3. #include <typeinfo.h>   
  4. #include <iostream>   
  5.   
  6. class  A{  
  7. public :  
  8.    // object for class needs vtable   
  9.    // for RTTI   
  10.    virtual  ~A();  
  11. };  
  12.   
  13. using   namespace  std;  
  14. int  main() {  
  15. A* a = NULL;  
  16.   
  17. try  {  
  18.    cout << typeid(*a).name() << endl;  // Error condition   
  19.    }  
  20. catch  (bad_typeid){  
  21.    cout << "Object is NULL"  << endl;  
  22.    }  
  23. }  

      bad_cast
      这个关键字和bad_typeid类似,是dynamic_cast转换失败时(一般是错误的想把基类转换为子类时,此时转换结果为空指针),会抛出的异常。

Type of the exceptions thrown by dynamic_cast when they fail the run-time check performed on references to polymorphic class types.
The run-time check fails if the object would be an incomplete object of the destination type.
Its member what returns a null-terminated character sequence identifying the exception.
Some functions in the standard library may also throw this exception to signal a type-casting error.
      bad_cast也是一个类,定义在typeinfo文件中。看下面的例子,请至少使用vs2003(vc6对dynamic_cast实现都有问题)编译:

  1. // bad_cast example   
  2. #include <iostream>   
  3. #include <typeinfo>   
  4. using   namespace  std;  
  5.   
  6. class  Base { virtual   void  Member(){}};  
  7. class  Derived : Base {};  
  8.   
  9. int  main () {  
  10.   try   
  11.   {  
  12.     Base b;  
  13.     Derived& rd = dynamic_cast<Derived&>(b);  
  14.   }  
  15.   catch  (bad_cast& bc)  
  16.   {  
  17.      cerr << "bad_cast caught: "  << bc.what() << endl;  
  18.   }  
  19.   return  0;  
  20. }  

      mutable
      类的const成员函数是不能修改类的成员变量的(非静态数据成员),这个是编译器就保证的,但是如果想呢?那就用mutable吧,给成员变量用这个关 键字修饰后,编译器就不会找你的麻烦了,其实这个关键字也是被诟病比较多的,到底有什么用或者什么时候该用还没有什么结论,因为这个关键字有破坏类的封装 性的嫌疑。看个小例子:

  1. class  TestMutable  
  2. {  
  3. public :  
  4.  TestMutable()  
  5.  {  
  6.   m_data = 0;  
  7.  }  
  8.   
  9.  int  changeValue()  const   
  10.  {  
  11.   return  ++m_data;  
  12.  }  
  13. private :  
  14.  // int m_data; // 编译会有错误:error C2166: l-value specifies const object   
  15.  mutable int  m_data;  // 这个没有问题   
  16. };  
  17.   
  18.   
  19. int  main( int  argc,  char * argv[])  
  20. {  
  21.  TestMutable tsMutable;  
  22.  cout << tsMutable.changeValue() << endl;  
  23.  cout << tsMutable.changeValue() << endl;  
  24.  return  0;  
  25. }  

      volatile
      这个关键字以前介绍过,就不述说了。见http://blog.csdn.net/magictong/archive/2008/10/29/3175793.aspx

      explicit
      这个关键字有时候还是有用的,作用是禁止单参数的构造函数被自动类型转换(往往是将一个基本类型转换成一个对象,而且很隐晦)。用来修饰类的构造函数,表 明该构造函数是一个显示的构造函数,而不是隐式的构造函数,编译器针对隐式构造函数在遇到赋值运算符时会执行很多额外的自动转换,而用这个关键字就是告诉 编译器,别忙活啦,不要多此一举,这不是我想要的。

  1. class  ArrExplicit  
  2. {  
  3. public :  
  4.  // ArrExplicit(int size) // 使用这句,编译器并不报错   
  5.  explicit  ArrExplicit( int  size)  // 下面arrExp = 102;编译器会报错   
  6.  {  
  7.   m_size = size;  
  8.  }  
  9.   
  10. private :  
  11.  int  m_size;  
  12. };  
  13. int  main( int  argc,  char * argv[])  
  14. {  
  15.  ArrExplicit arrExp(100);  
  16.  arrExp = 102; // 用explicit修饰后,编译报错   
  17.  return  0;  
  18. } 
http://blog.csdn.net/magictong/archive/2010/01/06/5139214.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值