在两个类中共享相同的函数调用,并在不需要时避免空实例化

Share same function call in two classes and avoid empty instantiation when not necessary

本文关键字:函数调用 不需要 实例化 两个 共享      更新时间:2023-10-16

我的问题:是否可以在两个继承的类(比如BaseDerived)之间共享对函数的相同调用,并且---关键点---当该函数严格特定于Base时,避免在Derived中使用空实例化,或者当该函数严格特定于Derived时,Base中避免空实例化?

共享同一调用的原因是几乎所有代码都是通用的,只是需要单独解决一些特殊性。例如:

class Base
{
virtual BaseSpecific();    // Useful in Base
virtual DerivedSpecific(); // Useless in Base
};
class Derived : Base
{
BaseSpecific() override;    // Useless in Derived
DerivedSpecific() override; // Useful in Derived
};
// f() is so similar between Base and Derived that is shared common in Base
Base::f()
{
...
BaseSpecific();
DerivedSpecific();
...
}
Derived::BaseSpecific() {}   // empty implementation in Derived, avoidable?
Base::BaseSpecific() { ... } // define the specific behavior in Base, OK
// or
Derived::DerivedSpecific() { ... } // define the specific behavior in Derived, OK
Base::DerivedSpecific() {}         // empty implementation in Base, avoidable?

C++是否为此提供了解决方案?这是不可避免的吗?

提前谢谢你。

PD:这类似于这个线程,但在实现上有所不同。

final关键字禁止覆盖该函数。所以BaseSpecific适合使用。如果我们不希望DerivedSpecificBase中实现,我们应该将其声明为pure abstract virtual function.

class Base
{
virtual void BaseSpecific() final;    // Useful in Base
virtual void DerivedSpecific() = 0;   // Not possible to implement here with this declaration
};
class Derived : Base
{
// void BaseSpecific() override; // Error, not possible to override
void DerivedSpecific() override; // It is possible to override
};

但如果你这么说

因为 Base 和 Derived 之间的代码 90% 相同,并且对于 剩下的10%,是专门做的。有可能改进吗?

合适的解决方案可能是实现模板方法模式。

借助链接示例的可能实现可能是:

#include <iostream>
#include <memory>
class Base
{
public:
void templateMethod()
{
stepOne();
stepTwo();
stepThree();
}
protected:
void stepOne() // And i dont want it to be overriden
{              // so it is not virtual
std::cout << "%45 of the code done." << std::endl;
} 
virtual void stepTwo() = 0;
void stepThree() // Again i dont want it to be overridden
{                // so it is not virtual
std::cout << "Remaining %45 of the work done." << std::endl;
}
}; 
class Derived : public Base
{
protected:
void stepTwo() override final // I want it to be final
{
std::cout << "%10 of the work done." << std::endl;
}
};
int main()
{
auto obj = std::make_unique<Derived>();
obj->templateMethod();
}

输出:

完成代码的 %45。
%10 已完成的工作。
剩余 %45 已完成的工作。

在线运行

还可以通过更改方法的声明来对模式执行条件操作。

例如:

bool stepTwo(); // Declaration
...
...
if ( stepTwo() ) // If second step succeeded
stepThree(); // Perform step three