我这是一个很好的实现,这个简单的继承不使用任何虚函数。
为什么我要这样:避免在性能关键代码中使用虚拟继承。 boost :: variant当然可以提供帮助,但我只想要标准的c ++东西:-)
我也参考了这个答案Link
#include <iostream>
using namespace std;
struct C;
struct B;
class A{
public:
A(int r): type(r){}
int type;
void deleter();
protected:
~A(){std::cout << "DTOR A" << std::endl;}
};
class B: public A{
public:
B():A(1){};
~B(){std::cout << "DTOR B" << std::endl;}
};
class C: public A{
public:
C():A(2){};
~C(){std::cout << "DTOR B" << std::endl;}
};
void A::deleter(){
if(type==1){
delete static_cast<B* const>(this);
}else if(type==2){
delete static_cast<C* const>(this);
}
}
int main(){
A * a = new B();
a->deleter();
}
我想使用基指针a
。主要问题是当我们想要delete a
时该怎么做。我只是通过DTOR
保护A
来禁止这种做法。因此,使用此构造的唯一方法是调用a.deleter()
以安全地删除bas类指针。
这是安全的,是一个很好的实现还是有更好的方法?
答案 0 :(得分:3)
您引用了一条指南“避免在性能标准代码中使用虚拟继承”。这不是一个糟糕的指导方针,但它不是最好的措辞。
真正的规则是“避免性能影响代码中的运行时多态性”。运行时多态性会导致性能下降。如果编译器不知道提前调用的确切函数,则无法跨函数进行优化。 (分支预测有帮助,但仍然远不及依赖于内联的优化)
要获得高性能和多态性,请在任何循环之外提升多态性。如果唯一的多态调用适用于大型操作,则不经常支付多态性的代价。
模板(编译时多态)可以帮助组成小型操作而无需重复代码。然后使用动态调度技术选择一个高度优化的模板实例。那时你使用的动态调度技术并不重要。虚拟调用,std::function
中的类型擦除,或者您自己的函数指针表。因为动态调度操作与实际工作相比较小。