2016-08-25 25 views
0

データベースクラスがあり、渡されたフラグに基づいて明示的なコンストラクタがデータベースに接続しようとします。失敗した場合はスローされます。これは望ましくない(データベースは別のアプリケーションで作成されたものではないかもしれない)ので、空のコンストラクタとデフォルトの移動コンストラクタを追加しました。ユーティリティクラスでは、データベースが作成され、新しいデータベースを移動するまで待つ。デフォルトの移動コンストラクタ

ユニットテストでは、移動する前にdatabase_utils::connected()がfalseを返すことがわかりました。しかし、私はデータベースを使用する関数を呼び出す場合、私はlibrary routine called out of sequenceエラーを取得します。これは私がデータベースまたは不正な選択ステートメントを開いていないことを示唆しますが、コンストラクタとデストラクタは正しい順序で呼び出され、データベースを作成し、それを移植しselect文が動作するデータベース自体の単体テストがあります。

私の質問デフォルトの移動は実際に移動されているかどうかですか?予想される行動を得るために何をする必要があるのでしょうか?

サンプルコード:

class database 
{ 
    database() : connected_(false), database_(nullptr) { } 
    database(/* params */) : connected_(false), database_(nullptr) { 
     /* attempt connection, throw on fail */ 
     connected_ = true; 
    } 
    database(database& other) = default; 
    database(database&& other) = default; 
    database& operator=(database&& other) = default; 
    ~database() { /* clean up */ } 
    operator bool() const { return connected_; } 

    bool connected_; 
    sqlite3* database_; 
}; 

class database_utils 
{ 
    database_utils() : db_() { } 
    void connect() { 
     db_ = std::move(database(/*params*/)); 
    } 
    bool connected() { return db_; } 
    void example_select(/* params */) { 
     /* use db_ */ 
    } 
    database db_; 
}; 
+0

移動コンストラクタが呼び出されたことを確認したい場合は、その中にデバッギングステートメントを入れて、それが出てくるかどうかを確認してください。もちろん、デフォルトコンストラクタには、データベースからの移動元オブジェクトのポインタがNULLになることはありません。これは確かにバグのように見えます。あなたは自分の移動コンストラクタを書く必要があります。それは正しいことです。 –

+0

[OT]:コピーコンストラクタは、そのargをconst参照で受け取ります。 – Jarod42

+1

おそらく、ダブルコンディションを避けるために、移動コンストラクタが移動したポインタをリセットしたいと思うかもしれません。 – Jarod42

答えて

2

デフォルトムーブコンストラクタはすべてを移動しません。

ただし、database_はポインタです。ポインタの移動は実際にはコピーです。

デストラクタでdatabase_が削除されます。

database_が同じメモリ位置を指しているため、database_はハイパースペースを指し示すため、「新しい」オブジェクトは非安定状態になります。

database_をスマートポインタに変更できる場合は、デフォルトの移動コンストラクタがうまく動作します。

また、すべてを移動する独自の移動コンストラクタを作成し、database_nullptrconnected_からfalseに設定します。

+0

私はポインタの動きがスワップされると思いますので、a-> 0x0000およびb-> 0x1234がa-> 0x1234およびb-> 0x0000になると思います。 –

+0

いいえ、これは間違っています。あなた自身の移動コンストラクタを行う場合、スワップは素晴らしいでしょうが、デフォルトのコンストラクタはスワップを行いません。 – Nick

関連する問題