2017-11-04 7 views
0

他のオブジェクトのコンストラクタで1オブジェクトのコンストラクタを呼び出そうとしていますが、削除する際に問題があります。コードの重要な部分は次のようになります:削除を呼び出さずに関数をC++に渡すコンストラクタ

class command { 
public: 
    command(const string& s) { 
     x = (char*) calloc(s.size()+1, 1); 
     memcpy(x, s.c_str()); 
    } 
    ~command() { 
     free(x); 
    } 
private: 
    char* x; 
} 

このコンストラクタmallocsは、デストラクタで解放する必要があるchar *です。

class pair { 
public: 
    pair(command comm1in, command comm2in) 
    :comm1(comm1in), comm2(comm2in){}; 
private: 
    command comm1; 
    command comm2; 
} 

この1つはで送信されたコマンドにその2つのフィールドを設定しようとします。 私は(ただし、間違っているかもしれない)、それはまた、彼らのコピーコンストラクタを呼び出すと思います

別の関数で、私はペアのコンストラクタを呼び出しますそう

pair p(command("something"), command("something else")); 

のように、残念ながら、これはペアのコンストラクタでコピーコンストラクタだけで作成された値にデストラクタを呼び出して、その後の効果があります。

コピー/削除プロセスを行わずにcomm1とcomm2を初期化する良い方法はありますか? 私はC++ 11がrValue参照とstd :: moveを持っていると思いますが、それらがここで再生されるかどうかはわかりません。

+7

を記述する必要はありません。 – Aganju

+4

@Aganjuあなたが自分のリソースを管理する必要がある状況にあっても正しい場合は、[3/5/0のルール(http://en.cppreference.com/w/cpp/language/ rule_of_three)。 –

+0

なぜ 'command'のコンストラクタとデストラクタにブレークポイントを設定しないのですか?次に、作成されて破棄されるオブジェクトのアドレスをそれぞれのケースで記録し、それらが一致しているかどうか、それぞれが何回呼び出されたかを確認することができます。これは、あなたに何が起こっているかのいくつかの洞察を与えるかもしれません。 – user1118321

答えて

-5

私はこれについて私の教授の一人に尋ねてから、遊んだ。 Thisは非常に役に立ちました。

ここで、ポインタxを二重にするのを避けたい場合は、上記のコードがどのように表示されるべきかを示します。 コマンド:

class command { 
public: 
    command(const string& s) { 
     x = (char*) calloc(s.size()+1, 1); 
     strcpy(x, s.c_str()); 
    } 
    command(command&& in): x(in.x) { 
     other.x = nullptr; 
    } 
    ~command() { 
     if(x) delete x; 
    } 
private: 
    char* x; 
} 

がペア:削除コンストラクタを呼び出す

が避けられないので、代わりに私たちが定義する必要があります。

class pair { 
public: 
    pair(command&& comm1in, command&& comm2in) 
    :comm1(std::move(comm1in)), comm2(std::move(comm2in)){}; 
private: 
    command comm1; 
    command comm2; 
} 

ペアのコンストラクタを呼び出すと、同じ

pair(command("something"), command("something else")); 

教訓を探しますRvを与えるコマンドのための移動コンストラクタalueのポインタを設定し、R値のポインタをnullに設定します。 (そう、そのデストラクタが、それはまだ先の尖った-に解放していないメモリと呼ばれたとき)

オブジェクトが別のオブジェクトに移動できるようにするために、STDでそれらを初期化::移動()

なぜこれを行いますか?

  • これにより、その1つのコマンドインスタンスだけがオブジェクトを持つことが保証されます。
  • malloc/newを呼び出す必要はなく、ヒープ上にスペースを確保する必要もありません。
  • コマンドはペアが削除されたときに自動的に削除されるので、あなたがC++である場合、我々は、malloc関数を使用して新しいとstd ::文字列を使用していない、削除機能に
関連する問題