#include <iostream>

struct A
{
    virtual void foo(){ std::cout << "A"; };
};

struct B : public A
{
private:
    void foo() override { std::cout << "B"; }
};

int main()
{
    A *p = new B;
    p->foo();      // prints B

//    B b;
//    b.foo();     // error: foo is private
    return 0;
}

// g++ -std=c++11 -Wall -Wextra -Wpedantic main.cpp && ./a.out

因此,我们可以多态调用B.foo(),但不能直接调用。当有人想要使用此功能时,是否有任何用例?

最佳答案

它在某种程度上取决于基类的设计。假设您有一个基类

class Stream {
public:
  virtual bool canSeek() = 0;
  virtual void seek(int offset) = 0;
};

注意:此示例来自.NET世界,其中基类库Stream类确实具有这样的虚拟CanSeek属性。我不想讨论这是否是好的设计,因为我可以看到双方的有效论点。这样的基类在现实中存在就足够了。

现在,派生类可以指定
class SpecificStream final : Stream {
private:
  virtual bool canSeek() { return false; }
  virtual void seek(int offset) { throw "no seek for you"; }
}

在此派生类中,根本实现了seek的事实是因为它在技术上是必需的。但是,处理此SpecificStream的任何代码都已经知道seek函数对于此类完全没有用,因此不应调用。当针对基本Stream类进行编码时,检查canSeek()的结果并仅在结果为true时才调用seek才有意义。当针对SpecificStream类进行编码时,检查canSeek()毫无意义,因为其结果是静态已知的,并且调用seek()绝对没有任何意义。如果这样的调用将是程序员错误,则有助于编译器为此类调用提供有用的消息是有意义的。

10-08 16:41