您的位置:首页 > 编程语言

polymorphic_cast 测试学习代码

2007-05-03 10:15 169 查看
#include <iostream>
#include <string>
#include "boost/cast.hpp"

class base1 {
public:
 virtual void print() {
  std::cout<<"base1::print/n";
 }
 virtual ~base1() {
 }
};

class base2 {
public:
 
 void only_base2() {
  std::cout << "only_base2()/n";
 }
 
 virtual ~base2() {}
};

class derived : public base1, public base2 {
public:
 
 void print() {
  std::cout << "derived::print()/n";
 }
 
 void only_here() {
  std::cout << "derived::only_here()/n";
 }
 void only_base2() {
  std::cout << "derived::only_base2,Oops, here too!/n";
 }
};
int main() {
 base1* p1=new derived;
 
 p1->print();
 
 try {
  derived* pD=boost::polymorphic_cast<derived*>(p1);
  pD->only_here();
  pD->only_base2();
  
  base2* pB=boost::polymorphic_cast<base2*>(p1);
  pB->only_base2();
 
 }
 catch(std::bad_cast& e) {
  std::cout << e.what() << '/n';
 }
 
 std::cout<<"..../n";
 base1 *p2 = new base1;
 try {
 
 derived&  dog = dynamic_cast<derived&>(*p2);
 dog.only_here();
 }
 catch(exception e ) {
  std::cout << e.what() << '/n';
 }

 delete p1;
}

/*
  /GR(启用运行时类型信息)

  说明:此选项 (/GR) 添加代码以便在运行时检查对象类型。当指定此选项时,编译器定义 _CPPRTTI 预处理器宏。默认情况下,此选项被清除 (/GR–)。
 
 在 Visual Studio 开发环境中设置此编译器选项
 
   打开此项目的“属性页”对话框。
   单击“C/C++”文件夹。
   单击“语言”属性页。
   修改“启用运行时类型信息”属性。
  
 */

/*Output: 
   derived::print()
   derived::only_here()
   derived::only_base2,Oops, here too!
   only_base2()
....
Bad dynamic_cast!
*/

dynamic_cast提供了两种转换方式,把基类指针转换成派生类指针,或者把指向基类的左值转换成派生类的引用。

 std::cout<<"..../n";
 base1 *p2 = new base1;
 try {
 
 derived*  dog = dynamic_cast<derived*>(p2);
 if ( dog != 0)
   dog->only_here();
 else
   std::cout<<"fail"<<std::endl;
 }
 catch(exception e ) {
  std::cout << e.what() << '/n';
 }
Output: fail

===========

Even without polymorphic_cast, if people know about the different ways that dynamic_cast works, it is still possible to achieve the same level of safety, as is shown in the following example.

void failure_is_error(base1* p) {

  try {
    some_other_class& soc=dynamic_cast<some_other_class&>(*p);
    // Use soc
   }
  catch(std::bad_cast& e) {
    std::cout << e.what() << '/n';
  }
}

void failure_is_ok(base1* p) {
  if (some_other_class* psoc=
    dynamic_cast<some_other_class*>(p)) {
    // Use psoc
  }
}

In this example, the pointer p is dereferenced[5] and the target type of the conversion is a reference to some_other_class. This invokes the throwing version of dynamic_cast. The second part of the example uses the non-throwing version by converting to a pointer type.

ps:
    template <class Target, class Source>
    inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
    {
        assert( dynamic_cast<Target>(x) == x );  // detect logic error
        return static_cast<Target>(x);
    }

polymorphic_downcast tests the cast with dynamic_cast, but only in debug builds; it then uses static_cast to perform the conversion.

static_cast is faster but unsafe!! 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息