如何在子类中重写时调用私有虚拟基类实现

How to call private virtual base class implementation when overriding in child class

本文关键字:虚拟 基类 实现 调用 子类 重写      更新时间:2023-10-16

>我有一个这样的类层次结构:

class Base
{
public:
void start() { init(); }
private:
virtual void init() = 0;
};
class Default : public Base
{
private:
virtual void init() override {/*default implementation*/};
};
class Special : public Default
{
private:
virtual void init() override final {/*specialized implementation*/};
}

如果我在Special类型的对象上调用start(),这工作正常;

现在我有一个案例,在Special类的实现中,我想调用Default类的实现。 通常这适用于Default::init();,但由于Default声明这是private,因此在这里会失败。

显然,一种解决方案是将其从private更改为protected,但我想问一下是否有其他方法?与其允许任何子函数直接调用此函数,我想将其限制为通过已在BaseDefault类中定义的虚函数发起的调用。

是否有一些选项或修饰符允许仅允许从子类调用成员函数,如果它们位于(相同(覆盖虚拟成员函数内?

>C++没有提供直接实现此目的的方法,因此您必须解决此问题,例如在下面的代码段中。

好吧,如果你绝对愿意的话。我个人宁愿回到保护函数,记录它们的用途和调用时间,然后相信派生类会正确地完成这些工作。最终,这可以使接口保持干净,并且不依赖于相当不寻常(也许是丑陋(的模式(实际上传递了两次this(。

class Base
{
public:
virtual ~Base() { }
void start()
{
InitProxy p(*this);
init(p);
}
protected:
class InitProxy
{
public:
InitProxy(InitProxy const&) = delete;
void init()
{
m_base.Base::init(*this);
}
private:
friend class Base;
Base& m_base;
InitProxy(Base& base)
: m_base(base)
{ }
};
private:
virtual void init(InitProxy& proxy) { }
};
class Derived : public Base
{
void init(InitProxy& proxy) override
{
proxy.init();
}
};

如果要将此约束应用于多个函数,则可以让代理接受成员函数指针,这样就不必为每个函数单独重写代理。如果函数参数不同,您可能需要从那时起制作一个模板。

向前声明Special,并使其成为Default的朋友:

class Base
{
public:
void start() { init(); }
private:
virtual void init() = 0;
};
class Special;  // Forward declaration
class Default : public Base
{
private:
virtual void init() override {/*default implementation*/}
friend class Special; // Friend declaration
};
class Special : public Default
{
private:
virtual void init() override final {
Default::init();
/*Other implementation*/
}
};