#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()
,但不能直接调用ORDER BY MyColumn ASC
。当有人想要使用此功能时,是否有任何用例?
答案 0 :(得分:5)
这取决于基类的设计。假设你有一个基类
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()
的结果并仅在结果为真时调用seek
可能是有意义的。在对SpecificStream
类进行编码时,检查canSeek()
是没有意义的,因为其结果是静态已知的,并且调用{{1}无疑是没有意义的。 }。如果这样的调用是程序员错误,那么帮助编译器为这些调用提供有用的消息是有意义的。
答案 1 :(得分:2)
它阻止你以非多态方式调用方法,这就是全部:使用范围解析运算符直接访问方法会导致难以维护代码。在一个你不知道每个人都是经验丰富的实现者的环境中(科学程序员可能会为大型代码库做贡献),引入模式来保护你的代码是值得的!
也就是说,Java明确禁止它,因为他们认为它的风格很糟糕。