[英]When inheriting from public interface, why it doesn't matter if the implementation is public or private?
我可能对C ++感到疲倦或距离太久,但是今天这真的让我感到惊讶:
#include <iostream>
class Interface
{
public:
virtual int aa() const = 0;
virtual int bb() const = 0;
};
class Usage : public Interface
{
private:
virtual int aa() const
{
int a = 10 * 10;
return a;
}
virtual int bb() const
{
int b = 20 * 20;
return b;
}
};
int main(int argc, char* argv[])
{
Interface* i = new Usage();
std::cout << i->bb() << std::endl;
return 0;
}
我希望编译器和/或链接器会抱怨函数签名错误或至少缺少实现。 考虑到这样做是可行的,当公共/受保护/私有修饰符被顶级声明隐藏时,它的含义是什么?
在C ++中如何调用此规则?
该标准的第11.6.1段对此进行了规定:
虚拟函数的访问规则(第11节)由其声明确定,并且不受以后覆盖该函数的函数规则的影响。 [ 示例-与您的基本相同 ]在调用点使用用于表示为其调用成员函数的对象的表达式的类型检查访问。 通常不知道在定义成员函数的类中对成员函数的访问。
Interface* i = new Usage();
std::cout << i->bb() << std::endl;
之所以起作用,是因为函数名称是根据对象的static
类型解析的。
这里的对象是i
其static
类型为Interface*
,其public
函数名称为bb()
。 因此,编译器看不到任何问题,因为调用成员函数的要求已满足。
还要注意,可访问性( public
, private
和protected
)是编译时构造。 在运行时,没有这样的事情。 编译器只能在编译时检测到任何与可访问性相关的规则违规。 它不知道运行时会发生什么。
因此,即使i
指向类型为“ Usage
的对象,该对象在private
节中定义了bb()
,编译器也可以使用它,就像之前提到的i
的static
类型仍然是具有public
函数bb()
Interface*
。 编译器不必理会对象的动态类型以及它如何覆盖函数,因为它不能完全出于动态原因。 它在运行时确定。
private
意味着您不能从中继承。 您可以继承protected
或public
,但没有什么可以阻止您将可见性限制在顶级阶层中的较低级别(即, public
为protected
或private
;或protected
为private
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.