10

我有一個靜態成員的類。這將使用同一類的私有靜態函數進行初始化。在靜態成員初始化期間訪問私有靜態函數

#include <iostream> 
#include <string> 

class A 
{ 
public: 
    static std::string const s; 

private: 
    static std::string make() 
    { 
     return "S"; 
    } 
}; 

std::string const A::s = A::make(); 

int main() 
{ 
    std::cout << A::s << std::endl; 
    // std::cout << A::make() << std::endl; // <-- Does not work 
    return 0; 
} 

我的問題是:因爲哪個規則是允許的?顯然,評論部分不起作用,因爲我不允許從課外訪問私人功能。那麼爲什麼啓動期間私有靜態成員的初始化是一個特殊情況? (並在旁註:這條規則的意圖是什麼?是否允許這個確切的情況?)

我知道其他機制來初始化靜態成員(如這裏:Initializing private static members)。但在我的情況下,該成員是const,所以據我所知,設定它的唯一方法是通過定義處的直接初始化。

回答

8

由於靜態數據成員的初始化被認爲是類的表徵的一部分,即使靜態數據成員是在名稱空間範圍(類定義之外)定義的。

從標準,$9.2.3.2/2 Static data members [class.static.data]

(重點煤礦)

在靜態數據成員定義中的初始化表達式是同類([basic.scope的範圍。類])。

[實施例:

class process { 
    static process* run_chain; 
    static process* running; 
}; 

process* process::running = get_main(); 
process* process::run_chain = running; 

process類的run_chain在全球範圍 定義的靜態數據成員;符號process::run_chain指定成員 run_chain是類process的成員並且在類 process的範圍內。在靜態數據成員定義中,初始化程序 表達式引用類process的靜態數據成員running。 - end example]

+1

你是對的const。編輯了這個問題。謝謝。 –

+1

我認爲這會更清楚,因爲「儘管靜態數據成員是在名稱空間範圍(類定義之外)定義的,靜態數據成員的初始化被認爲是類的表徵的一部分」。 (我使用「特徵描述」,因爲「類定義」在C++標準中有非常正式的含義。) –

+0

@MartinBonner好。 – songyuanyao