2017-10-02 16 views
-5
#include <iostream> 

using namespace std; 

class Foo { 

    int i; 
    int * p = new int; 
    *p = 5; // This doesn't worl 
    // If I instead use int * p = new int(5); it works. 
}; 

なぜですか?私はこれがクラス内でのみ発生することがわかります、もし私がそれが動作するはずのメイン関数に同じコードを書くならば。クラス内の変数に値を代入できません

+1

有効でないものは有効な構文ではありません。 –

+2

このような式は関数内にある必要があるためです。 –

+2

一つは 'p'の初期化であり、もう一つは' * p'への代入です。ブロックスコープ外では初期化のみが許可されます。 – StoryTeller

答えて

0

この構文は無効です。クラス定義内にコードを書くことはできません。代わりに、関数を記述することができますし、あなたのコードは、その中に動作します:

class Foo { 
public: 
    void bar() { 
    int * p = new int; 
    *p = 5; 
    } 
}; 

int main(int argc, char ** argv) { 
    Foo f; 
    f.bar(); 
} 

注:あなたは割り当て、可能な場合、単一のステートメントでは、あなたの変数を初期化することを好む必要があります。その代わり

int *p = new int(5); 

of:

+0

これはデフォルトでは 'p'を初期化しません... –

+0

できるだけ質問に近い例を残そうとしました。どうしてそれはあなたを悩ませるのですか? –

+0

私を悩ますことはありません:-)しかし、 'int * p = new int(5)'の場合、 'p'はオブジェクト構築の過程で初期化されます。いくつかの状況では、例えば、 'Foo'オブジェクトのベクトルをデフォルトで初期化するとき、オブジェクト作成後にメソッドを呼び出さなければならないということは非常に不便です。 –

2

メンバーを動的に割り当てる必要があるという前提で、どのような理由であれ(そのクラスは再設計されるべきですが、それは別の問題です。クラス定義内の変数の初期化の一環として、文のカップルを実行するには

、あなたがラムダでそれをラップし、それをすぐに呼び出すことができます。

class Foo { 
    int i; 
    int * p = []() { 
     auto *ret = new int; 
     *ret = 5; 
     return ret; 
    }(); // <-- Invokes the lambda right away 
}; 

のみ初期化は、名前空間とクラススコープで許可されています。他のステートメントは、ラムダが提供するブロックスコープで表示する必要があります。

しかし、それは面倒です、悪いアドバイス、あなたは本当にしなければならない限り、それを行うべきではありません。コンストラクターの定義が良いでしょう。

+0

あなたの答えStoryTellerに感謝します。しかし、私はプログラミングに慣れていません。ラムダはどういう意味ですか? – user45147

2

クラス定義は、メンバー宣言(クラスにメンバーが含まれている場合)から成ります。クラス定義の宣言以外のステートメントは使用できません。

クラス定義

*p = 5; // This doesn't worl 

でこのステートメントは、宣言ではありません。代わりに、この二つの文

int * p = new int; 
*p = 5; // This doesn't worl 

のあなたのクラス定義では、生のポインタの代わりに使用できる標準的なスマートポインタstd::unique_ptrにちょうど宣言

int * p = new int(5); 

ご注意を書くことができます。この場合、オブジェクトはオブジェクトが存在しなくなると自動的に解放されます。たとえば

std::unique_ptr<int> p{ new int(5) }; 
関連する問題