当从公共接口继承时,为什么实现是公共的还是私有的并不重要?
我可能只是累了或者距离 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;
}
我希望编译器和/或链接器会抱怨错误的函数签名或至少抱怨缺少实现。考虑到这是有效的,那么当 public/protected/private 修饰符被顶级类声明隐藏时,它的含义是什么?
这个规则在C++中是如何调用的?
I might be very well just tired or too long far from C++ but this one really surprised me today:
#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;
}
I'd expect compiler and/or linker would complain about either bad function signature or at least about missing implementation. Considering this is working and ok, what is the meaning of public/protected/private modifiers when it's hidden by the top class declaration?
How does this rule call in C++ ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
标准第 11.6.1 段对此进行了规定:
This is specified in paragraph 11.6.1 of the standard:
这是有效的,因为函数名称是根据对象的静态类型解析的。
这里的对象是
i
,其static
类型是Interface*
,它有一个public
函数名称bb( )
。因此,编译器不会发现任何问题,因为调用成员函数的要求满足了。另请注意,可访问性(
public
、private
和protected
)是编译时构造。在运行时,没有这样的事情。编译器只能在编译时检测到任何与可访问性相关的违反规则的情况。它无法知道运行时发生了什么。因此,即使
i
指向一个类型为Usage
的对象,该对象已在private
部分中定义了bb()
,编译器对此没有问题,如前所述,i
的static
类型仍然是具有public
Interface*代码> 函数bb()
。编译器不会关心对象的动态类型以及它如何覆盖函数,因为它不能,正是因为它的动态;它是在运行时确定的。This is working because the function name is resolved based on the
static
type of the object.Here the object is
i
whosestatic
type isInterface*
which has apublic
function namebb()
. Hence, the compiler doesn't see any problem, as the requirement to call a member function meets it.Also note that accessibilities (
public
,private
andprotected
) are compile-time constructs. At runtime, there is no such thing. Compiler can detect any violation of rules related to accessibility at compile time only. It cannot know what happens at runtime.So even if
i
points to an object whose type isUsage
which has definedbb()
in theprivate
section, the compiler is fine with it, as noted before thestatic
type ofi
is stillInterface*
which has apublic
functionbb()
. The compiler doens't bother with the dynamic type of object and how it overrides the function, because it cannot, precisely for the reason that its dynamic; its determined at runtime.private
意味着你不能继承它。您可以继承protected
或public
,但没有什么可以阻止您将可见性限制在较低级别(即public
到protected< /code> 或
private
; 或protected
到private
) 在你的顶级类中。private
means you can't inherit from it.protected
orpublic
you can inherit from but there is nothing stopping you limiting the visibility to a lower level (i.e.public
toprotected
orprivate
; orprotected
toprivate
) in your top class.