2017-01-24 5 views
4

このコードは、私が望むやり方でコンパイルして動作させますが、なぜですか?プライベート静的メンバーを初期化するときにプライベート静的メソッドを呼び出すことが許可されるのはなぜですか?

#include <iostream> 

class Test { 
private: 
    static bool _inited; 
    static bool _init() { 
    std::cout << "init!" << std::endl; 
    return true; 
    } 
}; 

bool Test::_inited = Test::_init(); 

int main(int argc, char** argv) { 
} 

そして私は私が考えるものを作る場合は、無関係な変更ではありません:

bool _inited = Test::_init(); 

それはもはや私のプライベートメソッドを呼び出そうとについての予想されるエラーを与えて、コンパイルします。

+12

'Test :: _ inited'は' Test'クラスの一部です(静的データメンバ 'Test :: _ inited'の定義です) – milleniumbug

+2

' bool_inited = Test :: _ init(); 'それは無関係ではありません。メンバーの価値を他のものに与えることを試みるのではなく、単にクラスの外にメンバーを定義するだけです。 – George

+0

おそらく、それが最初のバージョンで動作するとは思わない理由を説明するのに役立ちます。 – Matt

答えて

2

答えは簡単です。あなたは

bool Test::_inited = Test::_init(); 

を書くときには、クラスTestのプライベート静的変数は()関数が返すの_initの値に等しい値を有することを意味します。そのスコープの外からプライベート関数にアクセスしようとしていないので完全に有効です。 Class_Name ::接頭辞は、それらをクラスの中に置きます。彼らはクラス宣言には入っていません。だから、クラス内に文全体を置くような方法で。あなたは

bool _inited = Test::_init(); 

を書込み禁止とき

は今_inited変数は、クラスTestのとは異なっています。したがって、ゲッター関数が割り当てに使用されていない限り、禁止されているクラスのプライベートデータメソッドからその価値が得られます。

4

このコードは、私が望む方法でコンパイルして動作しますが、なぜですか?

あなたが使用している場所では、クラスの一部としてクラススコープで動作しているためです。 (それはプライベートまたはパブリックにする)

static void Test::foo() { 
    Test::_init(); // or just _init(); 
} 

ここで、機能fooは明らかにクラスの一部であるので、あなたはTestのすべてのメンバーにアクセスすることができます。

それはあなたが書くした場合と同じになりますその中に。 (それはTestの一部だから)_initedが初期化されるときに、コンパイラはすでに、_init()ためTestの範囲で見られるので

あなたもTest::を削除することができ、それは冗長です。

1

私は次のことがかなり良いと思う。採取フォームhttp://www.cplusplus.com/doc/tutorial/classes/

スコープ演算子(::)この関数定義を直接、クラス定義内に含まれていた場合と全く同じスコープの特性を付与する、メンバーが宣言されるクラスが属する特定します。

静的フィールドを含め、クラス内のすべてに同じことが当てはまると思います。

+0

http://stackoverflow.com/questions/6520052/whats-wrong-with-cplusplus-com –

関連する問題