私有虚拟方法的用途是什么?

时间:2020-05-20 21:58:26

标签: c++ virtual-functions

考虑以下示例

#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,但是如在给定的私有虚拟示例中一样,

2 个答案:

答案 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:仅当派生类需要调用虚拟函数的基本实现时,才应将虚拟函数设置为受保护...

http://www.gotw.ca/publications/mill18.htm

相关问题