polymorphic_downcast、转型安全 与 运行时开销的考虑

来源:互联网 发布:minitab生成数据 编辑:程序博客网 时间:2024/06/15 22:38

有时候,使用dynamic_cast函数效率比较低,因为是运行时开销,我们最好使用static_cast,然而使用static_cast函数向下转型存在极大的危险[1]2.3.1,而且可能产生错误。所以,我们用dynamic_cast进行测试,安全后再采用static_cast进行向下转换;polymorphic_downcast函数使用dynamic_cast进行测试(仅在调试模式下有效),然后使用static_cast进行转换操作(两者兼顾,皆大欢喜!)。

在发布模式下,polymorphic_downcast只执行static_cast函数。这样好了:我们编程的次序也就出来了:如果需要向下转型,同时这个转型操作是性能的瓶颈的话,那么使用polymorphic_downcast吧!在debug模式下运行一遍,没错了,然后生成发布版本——既安全、又有效率。在测试的时候找出错误,总比听用户的尖叫要好一些。

 

下面看一些使用代码示例:

  1. #include <boost/cast.hpp>
  2. #include <iostream>
  3. using namespace std;
  4. using namespace boost;
  5. struct base
  6. {
  7.     virtual ~base(){};
  8. };
  9. struct derived1 : public base 
  10. {
  11.     void foo()
  12.     {
  13.         cout<<"derived1::foo()"<<endl;
  14.     }
  15. };
  16. struct derived2 : public base 
  17. {
  18.     void foo()
  19.     {
  20.         cout<<"derived2::foo()"<<endl;
  21.     }
  22. };
  23. void older(base* p )
  24. {
  25.     derived1* pd =static_cast<derived1*>(p);
  26.     pd->foo();
  27. }
  28. void newer(base* p )
  29. {
  30.     derived1* pd= boost::polymorphic_downcast<derived1*>(p);
  31.     pd->foo();
  32. };
  33. void main()
  34. {
  35.     derived2* p =new derived2;
  36.     older(p);   //转换能够成功,但是错误没被发现:转换成功,指针无效。
  37.     newer(p);
  38. }

一些建议:

1,如果正在使用向下转型,并且还需要在发行版本中获得static_cast函数的速度,那么就可以使用polymorphic_downcast函数;通过使用该函数,至少在测试阶段可以获得某些错误断言。

2,如果不能测试所有可能的转型,那么就不要使用polymorphic_downcast函数。

记住:这是一种优化方法,只有经过评测证明需要使用优化方法时,才可以应用它们。

 

题外话:

1,这些转型操作到底有多大的效率差异,尝试写一个时间评估函数,对比一下?

2,测试“向下转型安全”时,才用polymorphic_downcast,那么对于交叉转型的安全,这个函数能起作用吗?编程测试一下!

  1. #include <boost/cast.hpp>
  2. #include <iostream>
  3. using namespace std;
  4. using namespace boost;
  5. struct base
  6. {
  7.     virtual ~base(){}
  8. };
  9. struct base2 
  10. {
  11.     virtual ~base2(){}
  12. };
  13. struct derived2 : public base ,public base2
  14. {
  15. };
  16. void main()
  17. {
  18.     base* p =new derived2;
  19.     base2 * p2 = boost::polymorphic_cast<base2*>(p);   //It's OK for cross cast
  20. //  base2 * p3 = polymorphic_downcast<base2*>(p);    //no conversion from 'struct base *' to 'struct base2 *'
  21. }

看样子,polymorphic_downcast还只能处理“向下转型安全”的情况;对于交叉转型嘛,还是polymorphic_cast或者dynamic_cast适用。

 

参考文献:

1,超越C++标准库.Boost库导论

原创粉丝点击