2011-08-31 131 views
9

這個代碼編譯和運行沒有出錯時:爲什麼我可以從全局範圍調用私有構造函數?

class foo{ 
    static foo *ref; 
    foo(){} 
    public: 
    static foo *getRef(){ 
     return ref; 
    } 
    void bar(){} 
}; 

foo* foo::ref = new foo; // the construcrtor is private! 

int main(int argc, const char *argv[]) 
{ 
    foo* f = foo::getRef(); 
    f->bar(); 
    return 0; 
} 

有人能解釋爲什麼能構造被稱爲?

回答

15

該範圍不是全局的 - 靜態成員在類範圍內,所以它們的初始化表達式也在類範圍內。

+4

的確,用'foo * ref = new foo;'(注意不存在'foo ::')來替換表達式來獲得編譯器錯誤! –

10

答案是它在全局範圍內不可用。一個靜態成員的初始化器被定義爲裏面的類的作用域,所以它可以訪問私有成員。

§9.4.2/ 2 [...]靜態數據成員定義中的初始化表達式在其類(3.3.6)的範圍內。

-2

這種形式的靜態成員的初始化在舊的C++中不是必需的。它們在後來的C++版本中被強制執行。

而且,這種形式的靜態成員初始化通常用於在創建任何類對象之前初始化靜態成員。

(E.g) int MyClass::objectsCounter=0; 

但到了,

foo* foo::ref = new foo; 

這種說法你只是初始化通過創建一個新的對象的靜態成員(這是指針類型)。

在這種情況下,您通過調用其自己的類的私有方法來初始化私有成員。

因此,這裏沒有全球範圍的作用。

+0

-1你指的是C++的「舊版本」和「後期版本」*發佈版本? AFAIK,自1998年第一個標準以來,這已經成爲語言設計的一部分。而且,使用'new foo'總會創建一個對象。該語句執行兩件事:a)創建一個類型爲「foo」的實例;和b)爲'foo :: ref'分配一個指向新分配對象的指針。 –

+0

@AndréCaron感謝您的意見。我編輯了我的帖子。我其實只是想說這個信息。但是我錯誤地傳遞了這些信息。關於老的和後來的C++: - ,現在提供的信息來自完整的參考-HERBERT。 –

+0

如果您計劃使用專業C++編程,則應考慮使用[C++社區推薦的C++書籍](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 –

相關問題