polymorphic_downcast、转型安全 与 运行时开销的考虑
2008-11-06 22:10
141 查看
有时候,使用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模式下运行一遍,没错了,然后生成发布版本——既安全、又有效率。在测试的时候找出错误,总比听用户的尖叫要好一些。
下面看一些使用代码示例:
#include <boost/cast.hpp>
#include <iostream>
using namespace std;
using namespace boost;
struct base
{
virtual ~base(){};
};
struct derived1 : public base
{
void foo()
{
cout<<"derived1::foo()"<<endl;
}
};
struct derived2 : public base
{
void foo()
{
cout<<"derived2::foo()"<<endl;
}
};
void older(base* p )
{
derived1* pd =static_cast<derived1*>(p);
pd->foo();
}
void newer(base* p )
{
derived1* pd= boost::polymorphic_downcast<derived1*>(p);
pd->foo();
};
void main()
{
derived2* p =new derived2;
older(p); //转换能够成功,但是错误没被发现:转换成功,指针无效。
newer(p);
}
一些建议:
1,如果正在使用向下转型,并且还需要在发行版本中获得static_cast函数的速度,那么就可以使用polymorphic_downcast函数;通过使用该函数,至少在测试阶段可以获得某些错误断言。
2,如果不能测试所有可能的转型,那么就不要使用polymorphic_downcast函数。
记住:这是一种优化方法,只有经过评测证明需要使用优化方法时,才可以应用它们。
题外话:
1,这些转型操作到底有多大的效率差异,尝试写一个时间评估函数,对比一下?
2,测试“向下转型安全”时,才用polymorphic_downcast,那么对于交叉转型的安全,这个函数能起作用吗?编程测试一下!
#include <boost/cast.hpp>
#include <iostream>
using namespace std;
using namespace boost;
struct base
{
virtual ~base(){}
};
struct base2
{
virtual ~base2(){}
};
struct derived2 : public base ,public base2
{
};
void main()
{
base* p =new derived2;
base2 * p2 = boost::polymorphic_cast<base2*>(p); //It's OK for cross cast
// base2 * p3 = polymorphic_downcast<base2*>(p); //no conversion from 'struct base *' to 'struct base2 *'
}
看样子,polymorphic_downcast还只能处理“向下转型安全”的情况;对于交叉转型嘛,还是polymorphic_cast或者dynamic_cast适用。
参考文献:
1,超越C++标准库.Boost库导论
在发布模式下,polymorphic_downcast只执行static_cast函数。这样好了:我们编程的次序也就出来了:如果需要向下转型,同时这个转型操作是性能的瓶颈的话,那么使用polymorphic_downcast吧!在debug模式下运行一遍,没错了,然后生成发布版本——既安全、又有效率。在测试的时候找出错误,总比听用户的尖叫要好一些。
下面看一些使用代码示例:
#include <boost/cast.hpp>
#include <iostream>
using namespace std;
using namespace boost;
struct base
{
virtual ~base(){};
};
struct derived1 : public base
{
void foo()
{
cout<<"derived1::foo()"<<endl;
}
};
struct derived2 : public base
{
void foo()
{
cout<<"derived2::foo()"<<endl;
}
};
void older(base* p )
{
derived1* pd =static_cast<derived1*>(p);
pd->foo();
}
void newer(base* p )
{
derived1* pd= boost::polymorphic_downcast<derived1*>(p);
pd->foo();
};
void main()
{
derived2* p =new derived2;
older(p); //转换能够成功,但是错误没被发现:转换成功,指针无效。
newer(p);
}
一些建议:
1,如果正在使用向下转型,并且还需要在发行版本中获得static_cast函数的速度,那么就可以使用polymorphic_downcast函数;通过使用该函数,至少在测试阶段可以获得某些错误断言。
2,如果不能测试所有可能的转型,那么就不要使用polymorphic_downcast函数。
记住:这是一种优化方法,只有经过评测证明需要使用优化方法时,才可以应用它们。
题外话:
1,这些转型操作到底有多大的效率差异,尝试写一个时间评估函数,对比一下?
2,测试“向下转型安全”时,才用polymorphic_downcast,那么对于交叉转型的安全,这个函数能起作用吗?编程测试一下!
#include <boost/cast.hpp>
#include <iostream>
using namespace std;
using namespace boost;
struct base
{
virtual ~base(){}
};
struct base2
{
virtual ~base2(){}
};
struct derived2 : public base ,public base2
{
};
void main()
{
base* p =new derived2;
base2 * p2 = boost::polymorphic_cast<base2*>(p); //It's OK for cross cast
// base2 * p3 = polymorphic_downcast<base2*>(p); //no conversion from 'struct base *' to 'struct base2 *'
}
看样子,polymorphic_downcast还只能处理“向下转型安全”的情况;对于交叉转型嘛,还是polymorphic_cast或者dynamic_cast适用。
参考文献:
1,超越C++标准库.Boost库导论
相关文章推荐
- 你的.net 2.0 真的能与1.1 安全正确地运行在同一台电脑上吗? 小心Server Application Unavailable 错误
- asp.net 实现动态显示当前时间(不用javascript不考虑开销)
- 组策略gpedit查看服务services,报安全设置禁止运行该页中activeX控件该页无法正常显示
- 当前安全设置禁止运行该页中activeX控件,该页无法正常显示
- 企业杀毒软件应考虑移动安全解决方案
- 操作集合的线程安全考虑——java
- polymorphic_cast, dynamic_cast, polymorphic_downcast
- 第二十九条:优先考虑类型安全的异构容器
- 首席技术官应该考虑的网络安全问题 IT大咖说 - 大咖干货,不再错过
- 如何实现多个线程同步 (2013-11-10 12:07:24)转载▼ 标签: it 在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题,Java实现线程同步的方法很多
- 数据库设计中的安全考虑
- 本地运行swf访问网络的安全问题解决办法
- Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种运行模式。
- 允许java运行不安全或不可信的应用程序
- 让.net 2.0与1.1安全正确地运行在同一台电脑上运行
- 应用IPv6需要考虑的五个安全问题
- VC2005/2008 此网站的某个加载项运行失败,请检查“Internet选项 ”中的安全设置是否存在潜在冲突
- Active 控件调用DLL,因为安全透明性问题无法运行
- iOS应用程序安全(23)-对抗运行时分析和操作
- Web 应用开发时应该考虑的安全问题