1

Herb Sutter 的著名文章Virtuality指出:

准则#2:更喜欢将虚函数设为私有

这很容易。这使派生类可以覆盖函数以根据需要自定义行为,而无需通过使派生类可调用虚函数来直接公开虚函数(如果函数刚刚受到保护,则可能如此)

在下面的代码中,private_base_func()是在基类中声明的私有虚函数,并在驱动类构造函数中调用,奇怪的是,这段代码编译得很好,它从驱动类中调用了基类的私有虚函数,它与上述说法相矛盾。这让我很困惑。

class base
{
public:

    base() {}
    virtual ~base(){}

private:
    virtual void private_base_func() 
    { 
        std::cout << "Base Class invoke" << std::endl;
    }

};


class drived : public base
{
public:
    drived()
    {
        private_base_func(); // this line should not compile
    }

private:
    // Overriding base class virtual function
    void private_base_func() 
    { 
        std::cout << "Drived class invoke" << std::endl;
    }
};

int main()
{
   base* ptr = new drived();
   return 0;
}

提前感谢您的回复

4

2 回答 2

8

那是因为您正在调用drived的版本private_base_func,当然可以在drived. 不能调用的函数是base的版本:

drived()
{
    base::private_base_func(); // this line will not compile
}
于 2013-04-03T21:03:49.280 回答
1
    private_base_func(); // this line should not compile

怎么会这样?private_base_func是一个private函数 indrived并且该行在 inside drived,所以调用它是完全可以的。请注意,这不同于:

drived()
{
    base b;
    b.private_base_func(); // this line does not compile
}

无论如何,这不是这篇文章的内容。文章的重点是基类中定义了两个不同的接口。一个是公共接口,它提供了您的基地用户需要的操作。另一个是一组虚函数,它定义了扩展提供给基类​​的操作。通过分离这两个接口,您可以将用户与提供者分离并获得灵活性。

于 2013-04-03T21:04:37.257 回答