什么更快:从虚拟基地向下投射还是交叉投射?
What's faster: down-cast from virtual base or cross-cast?
这有点假设,因为我不太担心性能-只是想知道哪个选项实际上是最快/最有效的,或者如果没有任何区别。
假设我有一个支持重载的访问者模板的下面代码:#define IMPLEMENT_VISITOR_WITH_SUPERCLASS(superclass)
typedef superclass visitor_super_t;
virtual void visit(Visitor& v) { v.visit(*this); }
//-----------------------------------------------------------------------------
// Implementation detail:
// Selective dispatcher for the visitor - required to handle overloading.
//
template <typename T>
struct VisitorDispatch {
static void dispatch(Visitor* v, T* t) { v->visit(*t); }
};
// Specalization for cases where dispatch is not defined
template <> struct VisitorDispatch<void> {
static void dispatch(Visitor* v, void* t) { throw std::bad_cast(""); }
};
//-----------------------------------------------------------------------------
// Derive visitors from this and 'Visitor'.
template <typename T>
class VTarget
{
public:
// Don't really need a virtual dtor.
virtual void dispatch(T& t) = 0;
};
//-----------------------------------------------------------------------------
class Visitor
{
public:
virtual ~Visitor() = 0;
template <typename T>
void visit(T& t) {
typedef VTarget<T> target_t;
target_t* tgt = dynamic_cast<target_t*>(this);
if (tgt) {
tgt->dispatch(t);
}
else {
// Navigate up inhertiance hierarchy.
// requires 'super' to be defined in all classes in hierarchy
// applicable to this visitor.
typedef typename T::visitor_super_t super;
super* s = static_cast<super*>(&t);
VisitorDispatch<super>::dispatch(this, s);
}
}
};
//-----------------------------------------------------------------------------
inline Visitor::~Visitor() {}
然后用于创建通用访问者:
class CommonBase {
IMPLEMENT_VISITOR_WITH_SUPERCLASS(void)
virtual ~CommonBase() = 0;
};
class A : public CommonBase {
IMPLEMENT_VISITOR_WITH_SUPERCLASS(CommonBase)
};
class B : public CommonBase {
IMPLEMENT_VISITOR_WITH_SUPERCLASS(CommonBase)
};
class MyVisitor
: public Visitor
, public VTarget<CommonBase>
, public VTarget<A>
, public VTarget<B>
{
public:
virtual void dispatch(CommonBase& obj);
virtual void dispatch(A& obj);
virtual void dispatch(B& obj);
};
使用访客最终得到dynamic_cast<>
从Visitor
到VTarget<T>
,这是一个交叉铸造。
可以实现的另一种方法是使Visitor
成为VTarget<T>
的虚拟基- MyVisitor
将不再需要直接从Visitor继承。然后,Visitor::visit代码中的dynamic_cast<>
将导致从虚基Visitor
向下强制转换。
执行强制类型转换时,一个方法比另一个方法快吗?还是只会因为拥有虚拟基地而受到大小惩罚?
嗯,看起来交叉转换方法比虚基方法快。
对于需要1次回滚到超类的访问,在100000000次迭代中,交叉转换方法耗时30.2747秒,虚拟基方法耗时41.3999秒,大约慢37%。
在没有回滚到超类重载的情况下,交叉转换耗时10.733秒,虚拟基类耗时19.9982秒(慢了86%)。
我更想知道dynamic_cast在这两种模式下是如何操作的,真的
相关文章:
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- 出于什么目的,非虚拟方法将与C++一起使用?
- 私有虚拟方法有什么用?
- 拥有"受保护的非虚拟析构函数"与"受保护虚拟析构构函数"有什么好处
- 将虚拟方法定义为私有方法时会发生什么情况?
- 不实现父类的虚拟方法有什么风险
- 什么是直接 X 虚拟表?
- 有什么理由在没有继承的情况下声明一个虚拟方法
- 我是否错过了什么,或者虚拟呼叫的性能并不像人们所说的那样糟糕
- C++不支持非成员虚拟功能的原因是什么?
- 当超过可能的虚拟地址数时会发生什么情况
- 当声明了虚拟析构函数但没有实现时会发生什么情况
- 虚拟和非虚拟成员函数的调用方式有什么区别?
- 如果私有虚拟函数被覆盖为派生类中的公共函数,那么问题是什么
- 在什么条件下,纯虚拟方法生成了
- 在多级继承中派生的虚拟基类会发生什么
- 虚拟类和抽象类在C++有什么用
- 什么'这是实现;半虚拟'方法
- 虚拟析构函数的用途是什么