C++ 将私有纯虚方法重写为 public
C++ override private pure virtual method as public
为什么会这样?
http://coliru.stacked-crooked.com/a/e1376beff0c157a1
class Base{
private:
virtual void do_run() = 0;
public:
void run(){
do_run();
}
};
class A : public Base {
public:
// uplift ??
virtual void do_run() override {}
};
int main()
{
A a;
a.do_run();
}
为什么我可以将 PRIVATE 虚拟方法重写为 public?
这种行为是有意的。如果一个方法是虚拟的,那么它意味着可以通过派生 类 进行自定义,而不管访问修饰符如何。
见here
根据https://en.cppreference.com/w/cpp/language/virtual#In_detail 重写基类的virtual
成员函数只关心函数名、参数、const/volatile-ness 和ref 限定符。它不关心 return 类型、访问修饰符或其他您可能希望它关心的事情。
链接参考还特别指出:
Base::vf does not need to be visible (can be declared private, or inherited using private inheritance) to be overridden.
我找不到任何明确允许执行此操作的内容,但覆盖规则不会阻止它。凭借 virtual
函数和覆盖现有函数且不禁止这种情况的函数,它是允许的。
如果您要问为什么语言是这样的,您可能需要问标准化委员会。
Why I can override PRIVATE virtual method as public???
因为你以错误的角度看待基方法是私有的。 B::do_run
私有意味着 "only members and friends of this class can use it"。要禁止派生 classes 覆盖它,我们需要单独的说明符,但我们可以简单地使其不是 virtual
。 Class A
另一方面允许任何人调用 A::do_run()
并且由 class A
设计师决定。所以没有像你看到的那样提升。
请注意,此实现不会更改基 class 的访问方式和构造:
Base& b = a;
b.do_run();
将不起作用。
我记得 Scott Meyers 在 "Effective C++" 中更详细地描述了它背后的一些基本原理。但关键的实用功能是能够在相反的方向上使用这种灵活性,在派生的 class 中用私有函数覆盖 public base class 成员,迫使客户端使用 base class 作为接口,不要试图直接使用应该保持隐藏实现的派生接口。
如果打算为base-class编写一个私有代码&以防止覆盖它的可能性,在baseclass中实现私有函数,并声明它final
,否则:什么时候应该有人使用私有虚拟机? ISOCPP.ORG FAQ
为什么会这样?
http://coliru.stacked-crooked.com/a/e1376beff0c157a1
class Base{
private:
virtual void do_run() = 0;
public:
void run(){
do_run();
}
};
class A : public Base {
public:
// uplift ??
virtual void do_run() override {}
};
int main()
{
A a;
a.do_run();
}
为什么我可以将 PRIVATE 虚拟方法重写为 public?
这种行为是有意的。如果一个方法是虚拟的,那么它意味着可以通过派生 类 进行自定义,而不管访问修饰符如何。
见here
根据https://en.cppreference.com/w/cpp/language/virtual#In_detail 重写基类的virtual
成员函数只关心函数名、参数、const/volatile-ness 和ref 限定符。它不关心 return 类型、访问修饰符或其他您可能希望它关心的事情。
链接参考还特别指出:
Base::vf does not need to be visible (can be declared private, or inherited using private inheritance) to be overridden.
我找不到任何明确允许执行此操作的内容,但覆盖规则不会阻止它。凭借 virtual
函数和覆盖现有函数且不禁止这种情况的函数,它是允许的。
如果您要问为什么语言是这样的,您可能需要问标准化委员会。
Why I can override PRIVATE virtual method as public???
因为你以错误的角度看待基方法是私有的。 B::do_run
私有意味着 "only members and friends of this class can use it"。要禁止派生 classes 覆盖它,我们需要单独的说明符,但我们可以简单地使其不是 virtual
。 Class A
另一方面允许任何人调用 A::do_run()
并且由 class A
设计师决定。所以没有像你看到的那样提升。
请注意,此实现不会更改基 class 的访问方式和构造:
Base& b = a;
b.do_run();
将不起作用。
我记得 Scott Meyers 在 "Effective C++" 中更详细地描述了它背后的一些基本原理。但关键的实用功能是能够在相反的方向上使用这种灵活性,在派生的 class 中用私有函数覆盖 public base class 成员,迫使客户端使用 base class 作为接口,不要试图直接使用应该保持隐藏实现的派生接口。
如果打算为base-class编写一个私有代码&以防止覆盖它的可能性,在baseclass中实现私有函数,并声明它final
,否则:什么时候应该有人使用私有虚拟机? ISOCPP.ORG FAQ