考虑以下示例
#include <iostream>
#include <string>
class A
{
public:
virtual void foo() { std::cout<< "FOO A\n"; }
private:
void bar() { std::cout<< "BAR A\n"; }
virtual void vbar() { std::cout<< "VBAR A\n"; }
};
class B : public A
{
public:
void foo() { std::cout<< "FOO B\n"; bar(); vbar(); }
private:
void bar() { std::cout<< "BAR B\n"; }
virtual void vbar() { std::cout<< "VBAR B\n"; }
};
int main()
{
A* b = new B();
b->foo();
}
输出将给我们
FOO B
BAR B
VBAR B
因为我首先想到了它的简单示例,所以我无法弄清任何私有虚拟方法用例。在使用公共虚拟方法的情况下,基指针类接口将适应其定义的vtable,但是如在给定的私有虚拟示例中一样,
答案 0 :(得分:1)
一种可能的用途是让基类定义结构,并让派生类实现所述结构(template method pattern)的组件的行为。例如,
struct foo
{
void do_stuff() {
// defines order in which some operations are executed
do_op1();
do_op1();
do_op3();
}
private:
// These don't have to be pure virtual. A base,
// default implementation could also be provided.
virtual void do_op1() = 0;
virtual void do_op2() = 0;
virtual void do_op3() = 0;
};
// implements the operations
struct foo1 : foo
{
private:
void do_op1() override { ... }
void do_op2() override { ... }
void do_op3() override { ... }
};
虚拟方法是私有的,因为孤立地调用它们是没有意义的。基类知道何时以及如何调用它们。
在“现代C ++”中实现此功能可能有更简单,更好的方法,但是这种事情可能在90年代和00年代就已经出现。
答案 1 :(得分:1)
有人认为,在某些情况下,它可能是有用的,它应该是首选方法,例如Herb Sutter:
准则2:更喜欢将虚拟功能设为私有。
...这可以使派生类重写函数以根据需要自定义行为,而无需进一步通过使派生类调用虚拟函数来直接公开虚函数(如果仅对函数进行保护,则可能会出现这种情况)。关键是存在虚拟功能以允许自定义。除非还需要直接在派生类的代码中调用它们,否则就不必将它们设置为私有。但是有时我们确实需要调用虚拟函数的基本版本(例如,请参见文章“ Virtually Yours” [5]),在这种情况下,保护那些虚拟函数才有意义,因此:
准则3:仅当派生类需要调用虚拟函数的基本实现时,才应将虚拟函数设置为受保护...