2011-06-27 29 views
1

我可能会很好只是累了或太长时间远离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++中调用?

回答

7

这在标准的段落11.6.1指定:

访问规则(第11),用于一个 虚拟功能是由其 声明确定,并且不受 用于规则函数,稍后 覆盖它。 [示例 - 基本上与您的相同] 使用所使用的表达式类型 来检查呼叫点 处的访问以表示调用成员函数的对象。 中定义的成员函数的成员函数的访问 通常不是已知的 。

+0

哈,就是这样,你让我。完美的答案。 –

1
Interface* i = new Usage(); 
std::cout << i->bb() << std::endl; 

这是工作,因为函数名是基于static类型对象的解决。

这里的对象是istatic类型是Interface*它有一个public函数名称bb()。因此,编译器没有看到任何问题,因为调用成员函数的要求满足它。

另请注意,可访问性(public,privateprotected)是编译时构造。在运行时,没有这样的事情。编译器只能在编译时检测任何违反与可访问性相关的规则。它无法知道运行时发生了什么。

因此,即使i指向的对象,其类型是Usage,其已在private部分定义bb(),编译器是与它的罚款,如所指出的前static类型的i仍然是Interface*具有public功能bb()。编译器不会为对象的类型以及它如何覆盖该函数而烦恼,因为它不能,正因为它的动态;动态;它在运行时确定。

-1

private意味着你不能从它继承。 protectedpublic您可以继承,但没有任何东西可以阻止您将知名度限制在顶级类别中的较低级别(即publicprotectedprivate;或protectedprivate)。

相关问题