派生类中的私有重写虚函数

Private overriden virtual functions in derived class

本文关键字:重写 函数 派生      更新时间:2023-10-16

如果虚拟成员函数在基类中是公共的,那么从基类中重写的虚拟成员函数是否有意义?

struct base {
virtual void a();
};
struct derived : base {
// ...
private:
void a() override;
};

如果您被迫在实现类上进行两阶段构造(即有一个init()方法以及或代替必须调用的构造函数(我知道,但有原因(,那么这将停止您直接在实例指针上调用任何/other/方法,然后再将其作为接口指针传递回。加倍努力,使继承私有,并让你的一个公共 init 函数返回接口指针!

另一个原因是你只是不需要/在最终的实现类声明中编写public:,所以默认情况下一切都是私有的。但是为什么你会这样做并使用结构而不是类我不知道。也许这是由于风格战争而在某个时候从阶级转换而来的?

看看你的设计,我发现不能直接调用derived::a,只能通过base接口调用。

有什么意义吗?考虑一下,一旦我们有一个derived实例,我们总是可以向上转换为它的基础,所以给定

derived d;

虽然d.a()不会编译,但我们总是可以

base & b = d;
b.a(); //which actually calls derived::a

换句话说:毕竟,derived::a不是那么私密,我不鼓励这种设计,这可能会让用户感到困惑。

如果derived中的私人成员在base中也是私有的,情况就会发生变化:这一次很明显,他们不能直接调用,在basederived之外。

假设我们有几个函数,并希望根据作为参数传递给第三个函数的值有条件地调用它们:

struct base 
{
void dosomething(bool x)
{
if(x)
{
do_this();
}
else
{
do_that();
}
}
private:
virtual void do_this(){}
virtual void do_that(){}
};

因此,派生类可以是这样的:

struct derived : base 
{
private:
void do_this() override { }
void do_that() override { }
};

并且没有其他类可以调用它们,除非它base自身扩展:

derived d;
d.dosomething(true); //will call do_this() in derived
d.dosomething(false); //will call do_that() in derived
d.do_that() //won't compile

是的,如果您将基类继承为私有。否则,它更像是一个奇怪的显式限制 - 用户必须进行显式转换才能使用该函数 - 通常不建议这样做,因为很少有人能够理解作者的意图。

如果要限制基类的某些函数,请进行私有/受保护的继承,并通过using关键字声明要在派生类中保护/公共的基方法。

与非虚拟方法相同的推理适用:如果只有类本身应该调用它,则将其设为私有。

考虑模板方法模式:

struct base {
void foo() { a() ; b(); }
virtual void a() = 0;
virtual void b() = 0;
};
struct derived : base {
private:
void a() override {}
void b() override {}
};
int main()
{
derived().foo();
}

也许应该protectedab,但无论如何,derived可以更改可访问性,并且需要一些文档,以便derived知道如何实现ab