1

コピーコンストラクターを含む次のクラスがあります。

ヘッダー ファイル: Fred.h

namespace foo {


class Fred {
private:
    int _x;
    int _y;


public:
    Fred();                         // Default constructor
    Fred(Fred const &other);        // Copy constructor
    Fred(int x, int y);             // Regular parameters
    ~Fred();                        // Destrcutor

};


}

実装ファイル: Fred.cpp

#include "Fred.h"
#include <iostream>

foo::Fred::Fred(){
    _x = 0;
    _y = 0;

    std::cout << "Calling the default constructor\n";
}

foo::Fred::Fred(Fred const &other){

    _x = other._x;
    _y = other._y;

    std::cout << "Calling the copy constructor";
}

foo::Fred::Fred(int x, int y){
    _x = x;
    _y = y;

    std::cout << "Calling the convenience constructor\n";
}

foo::Fred::~Fred(){

    std::cout << "Goodbye, cruel world!\n";
}

スコープ外になったときにデストラクタが呼び出されることを期待していましたが、代わりに、コピー コンストラクタが呼び出され、次にデストラクタが呼び出されました。なぜコピーが作成されたのですか?私はメモリをリークしていますか?

using namespace foo;

int main(int argc, const char * argv[])
{



    {
        Fred f2 = *new Fred();

    } // I was expecting to see a destructor call only


    return 0;
}
4

6 に答える 6

4

あなたがおそらく書くつもりだったのは:

Fred f2 = Fred();

またFred、ユーザー定義のデフォルト コンストラクターがあるため、次のように短縮できます。

Fred f2;
于 2013-08-23T12:30:41.373 に答える
2

C++ は、デフォルトで変数をスタックに割り当てます。Foo* foo = new Foo;あなたがやっていることのような文を書くときは、ヒープに割り当てている新しいオブジェクトを指すスタックにポインタを割り当てることです。
コードは、ポインターが指すオブジェクトが使用するメモリを解放するのを忘れているため、オブジェクトが解放されることはなく、そのデストラクタが呼び出されることもありません

このスレッドをチェックアウトすることをお勧めします: C++ で new キーワードを使用する必要があるのはいつですか?

于 2013-08-23T12:36:39.607 に答える
1

ヒープ上で新しく作成されたオブジェクトを逆参照して割り当てることによりFred f2、暗黙的にコピー コンストラクターを呼び出します。と同じです

Fred f1;
Fred f2 = f1;

さらに、ヒープ上のオブジェクトへのポインタを「失い」ます。これは自動的には削除されません --> Memory Leak


RAII を使用していない場合 (ただし使用する必要があります)、手動でクリアする必要があります。次のようになります。

using namespace foo;

int main(int argc, const char * argv[])
{



    {
        Fred* pF2 = new Fred();  // keep the pointer to manually delete

    } 
    // no destructor call even though scope is left --> delete manually
    delete pF2;
    pF2 = 0;

    return 0;
}
于 2013-08-23T13:57:16.820 に答える