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

来源:互联网 发布:mac 蓝色灯破解版 编辑:程序博客网 时间:2024/05/18 18:14

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没有实现:
view plaincopy to clipboardprint?
// expre_bad_typeid.cpp  
// compile with: /EHsc /GR 
#include <typeinfo.h> 
#include <iostream>  
 
class A{  
public:  
   // object for class needs vtable  
   // for RTTI  
   virtual ~A();  
};  
 
using namespace std;  
int main() {  
A* a = NULL;  
 
try {  
   cout << typeid(*a).name() << endl;  // Error condition  
   }  
catch (bad_typeid){  
   cout << "Object is NULL" << endl;  
   }  

// expre_bad_typeid.cpp
// compile with: /EHsc /GR
#include <typeinfo.h>
#include <iostream>

class A{
public:
   // object for class needs vtable
   // for RTTI
   virtual ~A();
};

using namespace std;
int main() {
A* a = NULL;

try {
   cout << typeid(*a).name() << endl;  // Error condition
   }
catch (bad_typeid){
   cout << "Object is NULL" << endl;
   }
}
 

      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实现都有问题)编译:
view plaincopy to clipboardprint?
// bad_cast example 
#include <iostream> 
#include <typeinfo>  
using namespace std;  
 
class Base {virtual void Member(){}};  
class Derived : Base {};  
 
int main () {  
  try 
  {  
    Base b;  
    Derived& rd = dynamic_cast<Derived&>(b);  
  }  
  catch (bad_cast& bc)  
  {  
     cerr << "bad_cast caught: " << bc.what() << endl;  
  }  
  return 0;  

// bad_cast example
#include <iostream>
#include <typeinfo>
using namespace std;

class Base {virtual void Member(){}};
class Derived : Base {};

int main () {
  try
  {
    Base b;
    Derived& rd = dynamic_cast<Derived&>(b);
  }
  catch (bad_cast& bc)
  {
     cerr << "bad_cast caught: " << bc.what() << endl;
  }
  return 0;
}
 

      mutable
      类的const成员函数是不能修改类的成员变量的(非静态数据成员),这个是编译器就保证的,但是如果想呢?那就用mutable吧,给成员变量用这个关键字修饰后,编译器就不会找你的麻烦了,其实这个关键字也是被诟病比较多的,到底有什么用或者什么时候该用还没有什么结论,因为这个关键字有破坏类的封装性的嫌疑。看个小例子:
view plaincopy to clipboardprint?
class TestMutable  
{  
public:  
 TestMutable()  
 {  
  m_data = 0;  
 }  
 
 int changeValue() const 
 {  
  return ++m_data;  
 }  
private:  
 // int m_data; // 编译会有错误:error C2166: l-value specifies const object  
 mutable int m_data; // 这个没有问题  
};  
 
 
int main(int argc, char* argv[])  
{  
 TestMutable tsMutable;  
 cout << tsMutable.changeValue() << endl;  
 cout << tsMutable.changeValue() << endl;  
 return 0;  
} 
class TestMutable
{
public:
 TestMutable()
 {
  m_data = 0;
 }

 int changeValue() const
 {
  return ++m_data;
 }
private:
 // int m_data; // 编译会有错误:error C2166: l-value specifies const object
 mutable int m_data; // 这个没有问题
};


int main(int argc, char* argv[])
{
 TestMutable tsMutable;
 cout << tsMutable.changeValue() << endl;
 cout << tsMutable.changeValue() << endl;
 return 0;

 

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

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

view plaincopy to clipboardprint?
class ArrExplicit  
{  
public:  
 // ArrExplicit(int size) // 使用这句,编译器并不报错  
 explicit ArrExplicit(int size) // 下面arrExp = 102;编译器会报错  
 {  
  m_size = size;  
 }  
 
private:  
 int m_size;  
};  
int main(int argc, char* argv[])  
{  
 ArrExplicit arrExp(100);  
 arrExp = 102; // 用explicit修饰后,编译报错  
 return 0;  
} 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/magictong/archive/2010/01/06/5139214.aspx