当前位置:首页
开发技术指南» 文章正文
    引言:
 

 

    摘要: 如何向dbgrid的一个字段自动添加当前时间和日期? ......
    摘要: i checked apache.org and find the /patch/forapache1.3.20 but it is empty please tell me where i can get the patch ......


请解释一下四个xxxcast的区别,谢谢.

请解释一下  
   
  const_cast  
  dynamic_cast  
  reinterpret_cast  
  static_cast  
   
  谢谢。  
 

NO.1   作者: cloudwu

C++   里最好杜绝使用   C   方式的强制转换,   换用以上   4   个.  
  我们通常用的是   static_cast  
  在一类东西都可以转,   但是不是一类的就不能转.  
  即,   语义上说不通的,   两个完全不同的数据类型   static_cast  
  是拒绝工作的.      
  比如你想把一个指针转成浮点数,  
  或者想把   class   A   *   转成     class   B   *   ,   但是   class   A   和   class   B  
  又没有任何关系.   等等....  
   
  static_cast   在通过编译后,   空间和时间效率实际等价于   C   方式强制转换.  
  都是编译时决定的.  
   
  dynamic_cast   类似   static_cast,   但是在一颗类继承树上转换时,  
  将利用   RTTI   在运行时检查.   我们一般用于   downcast  
   
  比如,  
  class   A   {};  
  class   B   :   public   A   {};  
   
  A*   a=new   B();  
   
  这个时候,   可以用   dynamic_cast   做   downcast,   把   a   转成   B*.  
  和   static_cast   不同,   dynamic_cast   会检查一下   a   到底是不是指向一个  
  B,   (利用了   RTTI)   如果转不了,   将返回一个   NULL.  
   
  reinterpret_cast   就比   static_cast   更接近   C   的强制转换了.  
  它更进一步的,   实现一些看起来没关系的两种类型转换.  
  比如我习惯干的,   把一个   void   *     转成   unsigned   ;)  
  当然它比   static_cast   危险.  
   
  但是有   reinterpret_cast   干不了的,  
  比如你在一个   const   成员函数里企图修改一个非   mutable   的成员变量.  
  编译器会对你咆哮,   "不许动,   那玩意是我   const   住的,   把你的爪子  
  收回去"   这个时候就要利用   const_cast   了,   呵呵.  
   
  const_cast   就是可以解除   const   限制的"神"的武器    
  但我认为,   这在很多情况下比   reinterpret_cast   更危险,   我还是老实做  
  人的好.   让编译器来捍卫我的代码的安全.  
   
 

NO.2   作者: yg88

这四个cast用来替代C里面包打一切类型转换的.  
  const_cast用来改变变量的“常数性”,例如:  
  void   func(const   int*   pcn)  
  {  
          int*   pn   =   const_cast<int*>(pcn);  
          *pn   =   10;  
  }  
   
  dynamic_cast用来把指向基类的指针安全地转化为指向派生类的指针,如果基类指针指向的对象不是派生类的对象,那么转换结果为NULL。例如,  
  CMainFrame*   pFrame   =   dynamic_cast<CMainFrame*>(GetParent());  
  如果调用GetParent的窗口的父窗口确实是CMainFrame类型,则pFrame指向  
  该窗口,否则pFrame为NULL。  
   
  static_cast也可以加基类的指针转化为派生类的指针,但不做运行是类型检查,所以可以隐含错误。此外,static_cast还可用于显式的类型转化,如将float转化为int,将int转化为double等等。例如:  
  int   i   =   3;  
  double   d   =   static_cast<double>(i);  
  这样做的好处是避免了编译时关于精度损失的警告信息。  
   
  reinterpret_cast是强力类型转换,进行所谓不合理的转换,或者说上面三个操作符无法进行的转换。例如把int转化为指向类的指针:  
  void   OnMessage(WPARAM   wParam,   LPARAM   lParam)  
  {  
          CMyClass*   pMyStructure    
                  =   reinterpret_cast<CMyClass*>(lParam);  
          ...  
  }  
  关于这四个运算符,我能说的最后一句话就是,请不要再用cast了,专心使用这四个啰嗦的运算符吧。他们会使你受益的。  
   
   
 

NO.3   作者: SystemAdministrator

 
  *   C++提供了四种新的类型强制:  
   
  static_cast  
  const_cast  
  reinterpret_cast  
  dynamic_cast  
   
  1)staic_cast静态强制;  
   
  不能在无关的指针之间进行static类型强制  
  class   CAnimal  
  {  
  //...  
  public:  
  CAnimal(){}  
  };  
   
  class   CGiraffe:public   CAnimal  
  {  
  //...  
  public:  
  CGiraffe(){}  
  };  
   
  int   main(void)  
  {  
  CAnimal   an;  
  CGiraffe   jean;  
   
  an   =   static_cast<CAnimal>(jean);//将对象jean强制成CAnimal类型  
  return   0;  
  }  
   
  2、const_cast类型强制  
   
  const_cast类型强制将一个const变量变成一个非const的等价形式  
  int   main()  
  {  
  const   int   j   =   99;  
  int   *   k;  
   
  k   =   const_cast<int   *>(&j);//解除const  
  return   0;  
  }  
   
  3、reinterpret_cast运算符  
   
  reinterpret_cast运算符用来将一个类型指针转变为另一种类型的指针,也用在将整开型量转为指针,或将指针转为整型量上;  
  int   main()  
  {  
  int   j   =   10;  
  int   *   ptr   =   &j;  
  char   *   cptr;  
   
  cptr   =   reinterpret_cast<char   *>(ptr);//将int指针类型转变为char的指针类型  
   
  return   0;  
  }  
   
  4、dynamic_cast运算符  
   
  dynamic_cast的主要目的是:  
   
  1)它返回派生类对象的地址;  
  2)它测试基类指针是否指向下一尖括号<>中所指定类型的对象  
   
  dynamic_cast是一个运行时类型信息,dynamic_cast运算符将指向派生对象的基类部分的基类指针转变为指向派生对象的派生类指针,dynamic_cast必须严格地指定与派生对象相同的类,或者它返回NULL指针;  
  class   CAnimal  
  {  
  //...  
  };  
  class   CGiraffe:public   CAnimal  
  {  
  //...  
  };  
  class   CGoat:public   CAnimal  
  {  
  //...  
  };  
   
  int   main()  
  {  
  CGiraffe   gene;  
  CAnimal   *   aptr   =   &gene;  
  CGiraffe   *   ptr1,*   ptr2;  
   
  ptr1   =   dynamic_cast<CGiraffe   *>(aptr);  
  ptr2   =   dynamic_cast<CGoat   *>(aptr); //return   NULL  
   
  return   0;  
  }  
 

NO.4   作者: sjie_ji

想不出比此更好的表达,请参阅more   effected   c++  
   
  条款2     尽量使用C++风格的类型转换  
  仔细想想地位卑贱的类型转换功能     cast       其在程序设计中的地位就象goto   语句一样令人鄙视     但是它还不是无法令人忍受     因为当在某些紧要的关头     类型转换还是必需的     这时它是一个必需品不过C风格的类型转换并不代表所有的类型转换功能     一来它们过于粗鲁     能允许你在任何类型之间进行转换     不过如果要进行更精确的类型转换     这会是一个优点     在这些类型转换中存在着巨大的不同     例如把一个指向const   对象的指针     pointer-to-const-object     转换成指向非const对象的指针     pointer-to-non-const-object    
  (即一个仅仅去除cosnt   的类型转换)   把一个指向基类的指针转换成指向子类的指针     即完全改变对象类型       传统的C风格的类型转换不对上述两种转换进行区分       这一点也不令人惊讶     因为C风格的类型转换是为C语言设计的     而不是为C++语言设计的     二来C风格的类型转换在程序语句中难以识别     在语法上类型转换由圆括号和标识符组成     而这些可以用在C         中的任何地方     这使得回答象这样一个最基  
  本的有关类型转换的问题变得很困难       在这个程序中是否使用了类型转换          
  这是因为人工阅读很可能忽略了类型转换的语句     而利用象grep   的工具程序也  
  不能从语句构成上区分出它们来    
  C++通过引进四个新的类型转换操作符克服了C风格类型转换的缺点     这四个操  
  作符是,   static_cast,   const_cast,   dynamic_cast,   和reinterpret_cast     在大多数情况下     对  
  于这些操作符你只需要知道原来你习惯于这样写    
  (type)   expression  
  而现在你总应该这样写    
  static_cast<type>(expression)  
  例如     假设你想把一个int   转换成double     以便让包含int   类型变量的表达式产生  
  出浮点数值的结果     如果用C风格的类型转换     你能这样写    
  int   firstNumber,   secondNumber;  
  ...  
  double   result   =   ((double)firstNumber)/secondNumber    
  如果用上述新的类型转换方法     你应该这样写    
  double   result   =   static_cast<double>(firstNumber)/secondNumber;  
  这样的类型转换不论是对人工还是对程序都很容易识别    
  static_cast   在功能上基本上与C   风格的类型转换一样强大     含义也一样     它也有  
  功能上限制     例如     你不能用static_cast   象用C风格的类型转换一样把struct   转换  
  成int   类型或者把double   类型转换成指针类型     另外     static_cast   不能从表达式中  
  去除const   属性     因为另一个新的类型转换操作符const_cast   有这样的功能    
  其它新的C++类型转换操作符被用在需要更多限制的地方     const_cast   用于类型  
  转换掉表达式的const   或volatileness   属性     通过使用const_cast     你向人们和编译  
  器强调你通过类型转换想做的只是改变一些东西的constness   或者volatileness   属  
  性   这个含义被编译器所约束   如果你试图使用const_cast   来完成修改constness   或  
  者volatileness   属性之外的事情     你的类型转换将被拒绝     下面是一些例子    
  class   Widget   {   ...   };  
  class   SpecialWidget:   public   Widget   {   ...   };  
  void   update(SpecialWidget   *psw);  
  SpecialWidget   sw;   //   sw   是一个非const   对象    
  const   SpecialWidget&   csw   =   sw;   //   csw   是sw   的一个引用  
  //   它是一个const   对象  
  update(&csw);   //   错误!不能传递一个const   SpecialWidget*   变量  
  //   给一个处理SpecialWidget*类型变量的函数  
  update(const_cast<SpecialWidget*>(&csw));  
  //   正确     csw   的const   被显示地转换掉    
  //   csw   和sw   两个变量值在update  
  //函数中能被更新    
  update((SpecialWidget*)&csw);  
  //   同上     但用了一个更难识别  
  //的C   风格的类型转换  
  Widget   *pw   =   new   SpecialWidget;  
  update(pw);   //   错误     pw   的类型是Widget*     但是  
  //   update   函数处理的是SpecialWidget*类型  
  update(const_cast<SpecialWidget*>(pw));  
  //   错误     const_cast   仅能被用在影响  
  //   constness   or   volatileness   的地方上     ,  
  //   不能用在向继承子类进行类型转换    
  到目前为止     const_cast   最普通的用途就是转换掉对象的const   属性    
  第二种特殊的类型转换符是dynamic_cast     它被用于安全地沿着类的继承关系向  
  下进行类型转换     这就是说     你能用dynamic_cast   把指向基类的指针或引用转换  
  成指向其派生类或其兄弟类的指针或引用     而且你能知道转换是否成功     失败的  
  转换将返回空指针     当对指针进行类型转换时     或者抛出异常     当对引用进行类  
  型转换时      
  Widget   *pw;  
  ...  
  update(dynamic_cast<SpecialWidget*>(pw));  
  //   正确     传递给update   函数一个指针  
  //   是指向变量类型为SpecialWidget   的pw   的指针  
  //   如果pw   确实指向一个对象,  
  //   否则传递过去的将使空指针    
  void   updateViaRef(SpecialWidget&   rsw);  
  updateViaRef(dynamic_cast<SpecialWidget&>(*pw));  
  //正确     传递给updateViaRef   函数  
  //   SpecialWidget   pw   指针     如果pw  
  //   确实指向了某个对象  
  //   否则将抛出异常  
  dynamic_casts   在帮助你浏览继承层次上是有限制的     它不能被用于缺乏虚函数的  
  类型上     参见条款24       也不能用它来转换掉constness:  
  int   firstNumber,   secondNumber;  
  ...  
  double   result   =   dynamic_cast<double>(firstNumber)/secondNumber;  
  //   错误     没有继承关系  
  const   SpecialWidget   sw;  
  ...  
  update(dynamic_cast<SpecialWidget*>(&sw));  
  //   错误!   dynamic_cast   不能转换  
  //   掉const    
  如你想在没有继承关系的类型中进行转换     你可能想到static_cast     如果是为了  
  去除const     你总得用const_cast    
  这四个类型转换符中的最后一个是reinterpret_cast   这个操作符被用于的类型转换  
  的转换结果几乎都是实现时定义     implementation-defined           因此     使用  
  reinterpret_casts   的代码很难移植    
  reinterpret_casts   的最普通的用途就是在函数指针类型之间进行转换     例如     假设  
  你有一个函数指针数组    
  typedef   void   (*FuncPtr)();   //   FuncPtr   is   一个指向函数  
  //   的指针     该函数没有参数  
  //   也返回值类型为void  
  FuncPtr   funcPtrArray[10];   //   funcPtrArray   是一个能容纳  
  //   10   个FuncPtrs   指针的数组  
  让我们假设你希望     因为某些莫名其妙的原因     把一个指向下面函数的指针存入  
  funcPtrArray   数组    
  int   doSomething();  
  你不能不经过类型转换而直接去做     因为doSomething   函数对于funcPtrArray   数组  
  来说有一个错误的类型     在FuncPtrArray   数组里的函数返回值是void   类型     而  
  doSomething函数返回值是int   类型    
  funcPtrArray[0]   =   &doSomething;   //   错误     类型不匹配  
  reinterpret_cast   可以让你迫使编译器以你的方法去看待它们    
  funcPtrArray[0]   =   //   this   compiles  
  reinterpret_cast<FuncPtr>(&doSomething);  
  转换函数指针的代码是不可移植的     C++不保证所有的函数指针都被用一样的方  
  法表示       在一些情况下这样的转换会产生不正确的结果     参见条款31       所以  
  你应该避免转换函数指针类型     除非你处于着背水一战和尖刀架喉的危急时刻    
  一把锋利的刀     一把非常锋利的刀    
  如果你使用的编译器缺乏对新的类型转换方式的支持   你可以用传统的类型转换  
  方法代替static_cast,   const_cast,   and   reinterpret_cast     也可以用下面的宏替换来模拟  
  新的类型转换语法    
  #define   static_cast(TYPE,EXPR)   ((TYPE)(EXPR))  
  #define   const_cast(TYPE,EXPR)   ((TYPE)(EXPR))  
  #define   reinterpret_cast(TYPE,EXPR)   ((TYPE)(EXPR))  
  你可以象这样使用使用    
  double   result   =   static_cast(double,   firstNumber)/secondNumber;  
  update(const_cast(SpecialWidget*,   &sw));  
  funcPtrArray[0]   =   reinterpret_cast(FuncPtr,   &doSomething);  
  这些模拟不会象真实的操作符一样安全   但是当你的编译器可以支持新的的类型转换时它们可以简化你把代码升级的过程    
  没有一个容易的方法来模拟dynamic_cast   的操作     但是很多函数库提供了函数安全地在派生类与基类之间的进行类型转换   如果你没有这些函数而你有必须进行这样的类型转换     你也可以回到C风格的类型转换方法上     但是这样的话你将不能获知类型转换是否失败     当然     你也可以定义一个宏来模拟dynamic_cast   的功能     就象模拟其它的类型转换一样    
  #define   dynamic_cast(TYPE,EXPR)   (TYPE)(EXPR)  
  请记住     这个模拟并不能完全实现dynamic_cast   的功能     它没有办法知道转换是否失败我知道     是的     我知道     新的类型转换操作符不是很美观而且用键盘键入也很麻烦     如果你发现它们看上去实在令人讨厌     C风格的类型转换还可以继续使用并且合法   然而正是因为新的类型转换符缺乏美感才能使它弥补了在含义精确性和可辨认性上的缺点     并且使用新类型转换符的程序更容易被解析     不论是对人工还是对于工具程序       它们允许编译器检测出原来不能发现的错误     这些都是放弃C风格类型转换方法的强有力的理由     还有第三个理由     也许让类型转换符不美观和键入麻烦是一件好事


 ·关于触发器的问题    »显示摘要«
    摘要: 我想让数据库完成这样一件事情: 每天凌晨00:00时往表temp_table里插入一条记录,比如 insert into temp_table(temp_time) values(sysdate); commit; 该如何实现?不管使用触发器还是使用何种手段。 ......
» 本期热门文章:

©2000-2007 All Rights Reserved. 最佳浏览:1024X768 MSIE