在 child class 中覆盖时如何调用私有虚拟基础 class 实现
How to call private virtual base class implementation when overriding in child class
我有这样的 class 层次结构:
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
;
的 object 上调用 start()
,它会正常工作
现在我有一个案例,在 Special
class 的实现中我想调用 Default
class 的实现。
通常这会与 Default::init();
一起使用,但由于 Default
的声明是 private
.
,所以这里会失败
显然一个解决方案是将其从private
更改为protected
,但我想问一下是否还有其他方法?我不想让任何 child 直接调用此函数,而是希望将其限制为通过已在 Base
或 Default
class 中定义的虚函数启动的调用.
是否有一些选项或修饰符允许成员函数调用只允许来自 child classes,如果它们在(相同的)覆盖虚拟成员函数内?
C++ 不提供直接实现此目的的方法,因此您必须变通,例如。 G。在下面的一段代码中。
好吧,如果你绝对想要。我个人宁愿回过头来让函数受到保护,document 它们的用途和调用时间,然后只相信派生 类 来做这些事情正确的。这最终使界面更干净,并且不依赖于一个相当不寻常的(可能是丑陋的)模式(实际上传递 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*/
}
};
我有这样的 class 层次结构:
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
class 的实现中我想调用 Default
class 的实现。
通常这会与 Default::init();
一起使用,但由于 Default
的声明是 private
.
显然一个解决方案是将其从private
更改为protected
,但我想问一下是否还有其他方法?我不想让任何 child 直接调用此函数,而是希望将其限制为通过已在 Base
或 Default
class 中定义的虚函数启动的调用.
是否有一些选项或修饰符允许成员函数调用只允许来自 child classes,如果它们在(相同的)覆盖虚拟成员函数内?
C++ 不提供直接实现此目的的方法,因此您必须变通,例如。 G。在下面的一段代码中。
好吧,如果你绝对想要。我个人宁愿回过头来让函数受到保护,document 它们的用途和调用时间,然后只相信派生 类 来做这些事情正确的。这最终使界面更干净,并且不依赖于一个相当不寻常的(可能是丑陋的)模式(实际上传递 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*/
}
};