不使用虚拟功能,可以使用以下内容:
void BaseClass::functionName () { // BaseClass already has virtual functions
// some LONG code true for all derived classes of BaseClass
// ...
if (typeid (*this) == typeid (DerivedClass1))
// use functions of DerivedClass1 on dynamic_cast<DerivedClass1*>(this)
else if (typeid (*this) == typeid (DerivedClass2))
// use functions of DerivedClass2 on dynamic_cast<DerivedClass2*>(this)
// some LONG code true for all derived classes of BaseClass
// ...
}
只是我觉得将虚函数用于上述类似的东西并不是一个好主意,因为它只是一个专门用于派生类的小部分。然后,需要对所有派生类反复使用用于所有派生类的长代码(仅为此建议一个辅助函数)。当然,我已经测试了我的方法并且它有效(并且我认为没有性能损失),但我想知道这是否是可疑的做法。 如果if-else-if部分在函数中被多次使用怎么办?
如果所有派生类的公共代码是相对短的,那么最好使用虚函数,对吗?
答案 0 :(得分:2)
为什么不这样做:
void BaseClass::functionName () {
// some LONG code true for all derived classes of BaseClass
// ...
this->some_protected_virtual_member_function();
// some LONG code true for all derived classes of BaseClass
// ...
}
因此,公共部分不会重复,并且行为仍然可以轻松地在子类中具有扩展,而无需向父类添加另一个if
答案 1 :(得分:0)
除非类具有虚函数,否则您的代码将无法运行。 C ++只提供有限的反射:如果没有虚函数,则typeid(DerivedClass1)== typeid(DerivedClass2)。上面的代码也可能比简单地访问虚函数慢:你将为每种类型获得一个新的分支,而不是一个恒定的时间指针查找。
然而,上述代码的最大问题是它失去了多态性和封装。必须知道使用代码或DerivedClass1和DerivedClass2需要做什么。它需要知道DerivedClass1和DerivedClass2中的结构。此外,所有代码都堆积在一个地方,使这个功能可能有数百行。
答案 2 :(得分:0)
我认为你在这里寻找模板方法模式:只需使用你现有的非虚函数,并让它只调用具体类之间差异的一小部分代码。它的优点是看起来更漂亮。
void BaseClass::functionName () {
// some LONG code true for all derived classes of BaseClass
// ...
functionName_impl(); // Will be virtual (private or protected) and overriden in each child class to do the right work.
// some LONG code true for all derived classes of BaseClass
// ...
}
答案 3 :(得分:0)
class Base {
public:
void templated() {
// do some stuff
this->hook1();
// other stuff
if (/*cond*/) { this->hook2(); }
size_t acc = 0;
for (Stuff const& s: /*...*/) { acc += this->hook3(s); }
// other stuff
}
private:
virtual void hook1() {}
virtual void hook2() {}
virtual size_t hook3(Stuff const&) { return 0; }
}; // class Base
然后Derived
类可以自定义挂钩的行为。
警告:由于templated
方法不是virtual
,因此本质上非常严格。这既是一种美德又是这种模式的问题,这很好,因为如果你需要改变templated
方法,那么它就是在一个地方定义的,如果提供的钩子不足以定制它就很烦人行为。