2011-06-27 61 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)。

相關問題