2016-08-25 88 views
12

我有這個問題,因爲單例/命名構造函數。在這兩種情況下,真正的構造函數都是受保護的或私有的,都不能從外部訪問。靜態方法可以訪問同一個類的私有方法嗎?

例如,短命名構造是這樣的:

class A 
{ 
    public: 
    static A createA() { return A(0); } // named constructor 
    private: 
    A (int x); 
}; 
int main(void) 
{ 
    A a = A::createA(); 
} 

我認爲靜態方法只能通過現有對象訪問靜態數據成員,或者訪問專用數據/方法。 但是,在上面的代碼中,私有構造函數A()不是靜態的,在調用它時,也不存在任何對象。 所以我能想到的唯一解釋是靜態方法可以訪問同一類的非靜態私有方法。任何人都可以請肯定或否定我的想法,可能有一些解釋?

我很抱歉,如果這太微不足道了,但關鍵詞太常見了,我無法在數十個谷歌網頁上找到答案。提前致謝。

+0

DR; TL;是的,它可以。 – 101010

+0

我假設你犯了一個錯字,意思是「所以我能想到的唯一解釋是靜態方法可以訪問同一類的非靜態私有方法」而不是「... * static * ...」 –

+0

謝謝!你有一些我可以看的參考嗎? –

回答

0

您的靜態方法不訪問任何靜態成員,也不訪問現有實例的任何非靜態成員。
這只是創建一個新的實例。

+0

它的確如此。但構造函數不是實例方法。構造函數是私有的這一事實是無關緊要的:一個成員(靜態或無)可以訪問該類中定義的任何內容。 –

9

靜態成員函數具有與非靜態成員函數相同的訪問權限。所以是的,它可以訪問課堂中的任何公共,受保護和私有變量。但是,您需要將該類的實例傳遞給函數以便能夠訪問該成員。否則,靜態函數只能直接訪問類中的任何其他靜態成員。

+0

這就是我很困惑。當我調用構造函數時,該對象甚至不存在。那麼當沒有實例存在時,靜態函數可以訪問私有構造函數嗎? –

+0

@FlowCloud請參見下文:「靜態函數可以訪問私有成員,但除此之外,它就像在類之外定義的任何函數一樣。」爲了運行構造函數,你不需要一個對象。對於其他非靜態類方法,你可以。 – rainer

+0

簡而言之,這是規則。我的老闆喜歡說一個班總是自己的「朋友」。 –

1

在類的功能(包括static功能),所有private成員數據和功能都可以訪問,即使你正在處理一個不同實例函數內的類

您在編寫文檔時經常利用此操作複製構造函數賦值運算符

(我的老闆經常談論他想如何能夠禁止使用某種friend = delete;語法的這種行爲。)

+0

我不認爲靜態方法可以在沒有對象的情況下訪問私有數據成員,對吧?我更感興趣的是靜態方法是否可以訪問私有方法(構造函數)? //我在上面看到你的解釋。謝謝! –

+0

不,你總是需要一個對象來引用一個非靜態數據成員。但是一個靜態函數可以調用一個私有函數;在你的情況下*構造函數*。 –

+0

我明白了,謝謝。 –

1

是的,可以。靜態函數可以訪問私有成員,但除此之外,它就像在類之外定義的任何函數一樣。尤其是,由於它沒有this指針(即沒有「綁定」到任何特定實例),因此您將無法直接訪問任何成員(它們總是「綁定」到實例):如果您要做到這一點,你從什麼地方需要一個實例:

#include <iostream> 
using namespace std; 

class A 
{ 
    public: 
    static A createA() { return A(0); } 
    static void dosomething(A *a) { return a->something(); } 
    private: 
    A (int x) { cout << "ctor" << endl; } 
    void something() { cout << "something" << endl; } 
}; 

int main(void) 
{ 
    A a = A::createA(); 
    A::dosomething(&a); 
    return 0; 
} 
+0

這正是問題:當調用靜態方法來創建對象時,還沒有對象存在。那麼它如何能夠訪問私有構造函數呢? –

+0

我在上面看到了你的進一步解釋。謝謝! –

3

根據標準§11/ P2成員訪問控制[class.access] (重點煤礦)

類的成員還可以訪問類所有的名稱有權限訪問。成員函數的本地類可以訪問與成員函數本身可以訪問的名稱相同的 。

113)因此,訪問權限是傳遞和累積到嵌套和本地類

由於靜態成員函數是類的成員,因此它可以訪問該類可以訪問的所有名稱,從而訪問類本身的構造函數。

因此,在你的榜樣:

class A { 
    A(int x); 
public: 
    static A createA() { return A(0); } // named constructor 
}; 

靜態成員函數A::createA()訪問調用private構造A::A(int)

相關問題