对于这种不使用任何虚函数的简单继承,这是一个很好的实现。
我为什么喜欢这样:避免在性能关键代码中使用虚拟继承。 一个 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
。主要问题是当我们想删除一个
时该怎么做。我只是通过保护 A
的 DTOR
来禁止这样做。所以使用这个构造的唯一方法是调用 a.deleter()
来安全地删除一个 bas 类指针。
这是安全且良好的实现方式还是有更好的方法?
最佳答案
您引用了一条准则“避免在性能关键代码中使用虚拟继承”。这不是一个糟糕的指南,但它不是最好的措辞。
真正的规则是“避免性能关键代码中的运行时多态性”。运行时多态性会导致性能下降。如果编译器不知道提前调用的确切函数,则无法跨函数进行优化。 (分支预测有帮助,但仍然远不及依赖于内联的优化)
为了同时获得高性能和多态性,将多态性提升到任何循环之外。如果唯一的多态调用是针对大型操作,则您不会经常为多态付出代价。
模板(编译时多态性)可以帮助组合小操作而无需代码重复。然后您使用动态分派(dispatch)技术来选择一个高度优化的模板实例化。在这一点上,您使用哪种动态调度技术并不重要。虚拟调用,std::function
中的类型删除,或您自己的函数指针表。因为动态调度操作与实际工作相比是很小的。
关于c++ - 没有虚拟的多态行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26115269/