2009-06-06 3 views
2

私はC++の専門家ではなく、物事の仕組みを直感的に把握していません。私はこれが簡単な質問だと思う。私はオブジェクトを他のオブジェクトに渡すのに問題があります。私はポインタや参照を渡すことを避けることを望むでしょう。初期化されたオブジェクトがセットアップされると、タイトなループで何百万回も呼び出します。私はコマンドパターンのようなものだと思う。ここに問題の核心があります。私のヘッダコードのようなものされています簡単な質問:状態を持つオブジェクトを渡す、C++

class ObjectWithState { 
public: 
    ObjectWithState(int state) { // This constructor creates the problem! 
    state_ = state;  // everyting works with no constructor. 
    } 
private: 
    int state_; 
}; 

class TakesObject { 
public: 
    TakesObject(ObjectWithState obj) { 
    obj_ = obj; 
    } 
private: 
    ObjectWithState obj_; 
}; 

マイmain()関数は次のようになります。

test.h: In constructor 'TakesObject::TakesObject(ObjectWithState)': 
test.h:14: error: no matching function for call to 'ObjectWithState::ObjectWithState()' 
test.h:5: note: candidates are: ObjectWithState::ObjectWithState(int) 
test.h:3: note:     ObjectWithState::ObjectWithState(const ObjectWithState&) 

単純な答え:

int main() { 
    ObjectWithState some_object(1); 
    TakesObject takes_object(some_object); 
    return 0 
} 

私は、次のようなエラー(G ++)を取得しますか?

コピーコンストラクタと関係があるかどうかはわかりません。もしそうなら、ObjectWithStateのクラス定義を非常にきれいで短く保つ解決策を見つけようとしています。このライブラリのユーザは、TakesObject関数が使うような小さな関数をたくさん定義しています。理想的には、ObjectsWithStateのプログラマーは単純なオブジェクトの実装に専念する必要があります。あなたの投稿をコードで

class TakesObject { 
public: 
    TakesObject(ObjectWithState obj): obj_(obj) { 
    } 
private: 
    ObjectWithState obj_; 
}; 

TakesObjectコンストラクタは、最初に新しいObjectWithStateを構築しようとします:おそらく私は道に迷って行くよ...あなたがやりたいことは何

答えて

5

は、メンバー初期化構文を使用していますそのデフォルトコンストラクタobjobj_に渡す代入演算子を呼び出します。上記の例では、コピーコンストラクタを使用して直接obj_を構築しています。

あなたは、あまりにも、あなたのObjectWithStateクラスのコピーコンストラクタを定義する必要があります。

class ObjectWithState { 
public: 
    ObjectWithState(int state) { 
    state_ = state; 
    } 
    ObjectWithState(const ObjectWithState &rhs) { 
    state_ = rhs.state_; 
    } 
private: 
    int state_; 
}; 

あなたのクラス宣言からすべてのコンストラクタを省略した場合、コンパイラはあなたのためのデフォルトとコピーコンストラクタを提供しています。 のいずれかのコンストラクタを宣言すると、コンパイラはデフォルトまたはコンストラクタを提供しないので、独自に実装する必要があります。

+1

幸いですが、コピーコンストラクタを宣言する必要はありません。デフォルトのコピーコンストラクタが適切です。 – rlbond

+0

彼はコピーコンストラクタを宣言する必要があります。一度ObjectWithState(int)を宣言すると、デフォルトのコピーコンストラクタは失われます。 –

+0

ObjectWithState() {} ObjectWithState(int state) { state_ = state; } 動作するようです。初期化リストを使うにはconstコンストラクタも必要です。任意の方法でObjectWithStateを単純化できますか? – Tristan

1

コンストラクタを宣言しているため、このエラーが発生しています。クラスにコンストラクタを宣言していない場合のみ、コンパイラはデフォルトのコンストラクタを提供します。コンストラクタを宣言しているので、デフォルトのコンストラクタを取得しません。パラメータを持たないコンストラクタを明示的に宣言する必要があります。

+0

よろしくお願いいたします。これらの余分なコンストラクタをObjectwithStateに書く必要を避けるためにこれを行うより良い方法はないと思いますか? ObjectWithStateに本質的なものがあれば好きです。サブクラス化してベースにデフォルトのコンストラクタを置くべきですか? '()'コンストラクタは何かをする必要がありますか?それとも、単に 'ObjectWithState(){} 'なのですか? – Tristan

+0

もちろん、デフォルトのコンストラクタが必要な場合を除きます。 – rlbond

+0

上記の@regbond Gregのソリューションは、これを行うための「より正確な」方法です.IMO。コンストラクタでの初期化の使用とにかく常にコピーコンストラクタを用意する必要があります。あなたは誰があなたのオブジェクトをコピーするのか分からない。 – jdt141