派生中的私有重写虚函数 class
Private overriden virtual functions in derived class
如果基 class 中的 public 是从基 class 覆盖的虚拟成员函数,是否有必要制作虚拟成员函数?
struct base {
virtual void a();
};
struct derived : base {
// ...
private:
void a() override;
};
与非虚拟方法相同的推理适用:如果只有 class 本身应该调用它,则将其设为私有。
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();
}
也许 a
和 b
应该是 protected
,但无论如何 derived
可以改变可访问性并且它需要一些文档以便 derived
知道它应该如何实现 a
和 b
.
看看你的设计,我发现不能直接调用 derived::a
,只能通过 base
接口。
有什么意义吗?考虑一下,一旦我们有了一个 derived
实例,我们总是可以向上转换到它的基础,所以给定
derived d;
虽然 d.a()
无法编译,但我们总能做到
base & b = d;
b.a(); //which actually calls derived::a
换句话说:derived::a
不是 那 私有的,毕竟,我不鼓励这种设计,这可能会让用户感到困惑。
如果 derived
中的私有成员在 base
中也是私有的,情况也会发生变化:这次很明显,它们不能直接在 base
或 derived
。
假设我们有几个函数,并希望根据作为参数传递给第三个函数的值有条件地调用它们:
struct base
{
void dosomething(bool x)
{
if(x)
{
do_this();
}
else
{
do_that();
}
}
private:
virtual void do_this(){}
virtual void do_that(){}
};
因此派生的 class 可能是这样的:
struct derived : base
{
private:
void do_this() override { }
void do_that() override { }
};
并且没有其他 class 可以调用它们,除非它扩展了 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
是的,如果您将基 class 继承为私有。否则,它更像是一个奇怪的类似显式的限制 - 用户必须进行显式转换才能使用该函数 - 通常不建议这样做,因为很少有人能够理解作者的意图。
如果你想限制来自基础 class 的一些函数,进行 private/protected 继承并通过 using
关键字声明你想成为哪些基础方法 protected/public在导出的 class.
如果您被迫对实现进行两阶段构建 class(即有一个 init()
方法以及或代替必须调用的构造函数(我知道,但有原因),那么这会阻止您在将实例指针作为接口指针传回之前直接在实例指针上调用任何 /other/ 方法。多走一步,将继承设为私有,并拥有您的 public 初始化函数return 接口指针!
另一个原因是您只是/不需要/在最终实现 class 声明中编写 public:
,因此默认情况下一切都是私有的。但是为什么你会这样做并使用 struct 而不是 class 我不知道。也许这是由于样式 war?
在某个时候从 class 转换而来的
如果基 class 中的 public 是从基 class 覆盖的虚拟成员函数,是否有必要制作虚拟成员函数?
struct base {
virtual void a();
};
struct derived : base {
// ...
private:
void a() override;
};
与非虚拟方法相同的推理适用:如果只有 class 本身应该调用它,则将其设为私有。
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();
}
也许 a
和 b
应该是 protected
,但无论如何 derived
可以改变可访问性并且它需要一些文档以便 derived
知道它应该如何实现 a
和 b
.
看看你的设计,我发现不能直接调用 derived::a
,只能通过 base
接口。
有什么意义吗?考虑一下,一旦我们有了一个 derived
实例,我们总是可以向上转换到它的基础,所以给定
derived d;
虽然 d.a()
无法编译,但我们总能做到
base & b = d;
b.a(); //which actually calls derived::a
换句话说:derived::a
不是 那 私有的,毕竟,我不鼓励这种设计,这可能会让用户感到困惑。
如果 derived
中的私有成员在 base
中也是私有的,情况也会发生变化:这次很明显,它们不能直接在 base
或 derived
。
假设我们有几个函数,并希望根据作为参数传递给第三个函数的值有条件地调用它们:
struct base
{
void dosomething(bool x)
{
if(x)
{
do_this();
}
else
{
do_that();
}
}
private:
virtual void do_this(){}
virtual void do_that(){}
};
因此派生的 class 可能是这样的:
struct derived : base
{
private:
void do_this() override { }
void do_that() override { }
};
并且没有其他 class 可以调用它们,除非它扩展了 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
是的,如果您将基 class 继承为私有。否则,它更像是一个奇怪的类似显式的限制 - 用户必须进行显式转换才能使用该函数 - 通常不建议这样做,因为很少有人能够理解作者的意图。
如果你想限制来自基础 class 的一些函数,进行 private/protected 继承并通过 using
关键字声明你想成为哪些基础方法 protected/public在导出的 class.
如果您被迫对实现进行两阶段构建 class(即有一个 init()
方法以及或代替必须调用的构造函数(我知道,但有原因),那么这会阻止您在将实例指针作为接口指针传回之前直接在实例指针上调用任何 /other/ 方法。多走一步,将继承设为私有,并拥有您的 public 初始化函数return 接口指针!
另一个原因是您只是/不需要/在最终实现 class 声明中编写 public:
,因此默认情况下一切都是私有的。但是为什么你会这样做并使用 struct 而不是 class 我不知道。也许这是由于样式 war?