1

私は sqlite 用の小さなラッパー クラスを作成しています。データベースとの間でデータを取得するために、SQLiteValue というクラスがあります。クエリのデータをバインドすると、SQLiteValue インスタンスがスタック上に作成され、いくつかの関数に渡されます。クラスのスケルトンの概要は以下のとおりです。

class SQLiteValue : public SQLiteObject
{
private:            
    // stores a pointer to the data contained (could be of varying types)
    union 
    {
        int* i;
        double* d;
        std::string* s;
        std::wstring* ws;
        BYTE* b;
    } pdata;
            int type;



public:

    SQLiteValue(const char* val);
    SQLiteValue(const wchar_t* val);
    .. and so on for varying types
    virtual ~SQLiteValue();
};

オブジェクトは、いくつかのオーバーロードされたコンストラクターの 1 つによって作成されます。コンストラクターは、その型に基づいて pdata の「メンバー」をインスタンス化します。これは、このクラスにとって重要なことです。さて、問題です。コンストラクターをオーバーロードしているため、クリーンなメソッド呼び出しが得られ、SQLiteValue(xxx) を明示的に呼び出す必要はありません。そのため、関数の参照を実際に使用したくないので、次のように定義します。

void BindValue(const char* name, SQLiteValue value)
query->BindValue(":username", "user2"); // the "clean" method call

このように宣言すると、関数を呼び出すたびに新しいオブジェクトがインスタンス化されます (または同様のことですか?)。そのため、デストラクタは pdata に割り当てられたメモリを解放します。これは悪いです。

私が知りたいのはこれです。クリーンなメソッド呼び出しを保持しながら、私がやろうとしていることを達成するためのより良い方法はありますか? 現時点では、問題を解決する参照によって動作するプライベート関数がありますが、この方法はあまり好きではありません。参照を忘れがちで、同じ問題を再び追跡することになります。

ありがとう。

4

2 に答える 2

0

これは、右辺値参照が役立つ状況です。呼び出されるコンストラクタ/デストラクタの量は減りませんが、右辺値 (&&) コピー コンストラクタまたは operator= で一時クラス インスタンスの内部リソースを「盗む」ことができます。詳細はこちら: http://blogs.msdn.com/b/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx

右辺値参照コピー コンストラクターは、別のインスタンスの内部リソースを「この」インスタンスに移動し、別のインスタンス リソースを 0 にリセットするだけです。したがって、割り当て、コピー、および解放の代わりに、ポインターまたはハンドルをコピーするだけです。コード内の「user2」は、そのような一時的なインスタンス-右辺値参照です。

これは、C++0x 標準を実装するすべての C++ コンパイラに適用できます。

于 2012-07-12T11:31:06.767 に答える
0

BindValue を const 参照でパラメータを取るように変更します。

void BindValue(const char* name, const SQLiteValue &value)
于 2012-07-12T11:51:34.203 に答える