4

ここで簡単な質問です。コードにいくつかのクラスがありますが、そのうちの1つだけがこの問題を示しており、私は一生の間その理由を理解できません。クラスのインスタンスを作成すると、直後にデストラクタが呼び出されますが、クラスのインスタンスは実際には削除されていないように見えます。

クラスのインスタンスに影響を与えるデストラクタにdelete[]操作がなければ、私はそれを受け入れることができるかもしれません。

「三つのルール」などについてどこかで読んだので、何が欠けているのか見てみました。私はすでにデフォルトのコンストラクターとユーザー定義のコンストラクターを持っています。次に、コピーコンストラクターと呼ばれるものを追加しました。次のようなものです。

MyClass::MyClass(const MyClass &duplicate)
{
    variable1 = duplicate.variable1;
    variable2 = duplicate.variable2;
    // etc
}

この問題を引き起こす可能性のあるここで何が欠けていますか?

編集:要求されたコード。すべてが明確になるように、すべての名前を変更しました(このコードはまだ問題を抱えてコンパイルされています)。まず、ヘッダーファイルMyClass.h

#ifndef MYCLASS_H
#define MYCLASS_H
#ifndef UNICODE
#define UNICODE
#endif
#include <string>

class MyClass
{
public:
    MyClass();
    MyClass::MyClass(const MyClass &);
    MyClass(int, std::wstring inputWord, int);
    ~MyClass();

    int intOne;
    int intTwo;
};
#endif

次へMyClass.cpp

#include "MyClass.h"
#include <Windows.h>


MyClass::MyClass(const MyClass &duplicate)
{
    intOne = duplicate.intOne;
    intTwo = duplicate.intTwo;
}
MyClass::MyClass()
{
}

MyClass::~MyClass()
{
    MessageBox(NULL, TEXT("TEST"), TEXT("TEST"),0);
}

MyClass::MyClass(int intOneInput, std::wstring stringInput, int intTwoInput)
{
    intOne = intOneInput;
    intTwo = intTwoInput;
}

そして最後に、オブジェクトを作成する方法:

MyClass test(0, TEXT("TEST"), 0);

[opのコメントからコピー]

実際、私の最後のコメントをスクラッチします。デコンストラクターはその特定の行で呼び出されません(スコープ外になるまで)。そうする行は次のようにwords.push_back(MyClass(0, TEXT("TEST"), 0));宣言されます。std::vector<MyClass> words

4

4 に答える 4

2

オブジェクトが破棄されたときにデストラクタを呼び出す必要があります。を使用してオブジェクトを作成すると、オブジェクトnewを呼び出すときにデストラクタが呼び出さdeleteれます。それ以外の場合は、スコープ外になったときに呼び出す必要があります。デストラクタ内にブレークポイントを設定し、コールスタックを確認して、デストラクタを呼び出しているものを確認できます。それが役に立てば幸い。

[更新]printf一時的に作成されたオブジェクトと混同されないように、すべてのctorとdtorに以下を追加してみてください。

printf("ctor %p\n", this); // in constructors

printf("dtor %p\n", this); // in destructor

[アップデート]

words.push_back(MyClass(0, TEXT("TEST"), 0));

これにより、一時オブジェクトが作成されます。これは、stlコンテナ(などvector)が常に保存するものを「コピー」するためです。(「移動」が発生しない限り、ここで「移動」と値付けの説明を始めたくありません。)

于 2012-04-30T22:05:05.017 に答える
1

考えられる問題(ただし、詳細を確認する必要があります)は、コピーコンストラクターがシャドウコピーを実行し、オブジェクトを一時的なものからコピー構築することです。一時オブジェクトが破棄されると、一時オブジェクトによって保持されていたメモリが解放され、新しいオブジェクトは削除されたメモリへのポインタを持ちます。

1つの解決策は次のとおりです。コピー作成時にディープコピーを実行します。
http://www.learncpp.com/cpp-tutorial/912-shallow-vs-deep-copying/

もう1つは、生のポインターの代わりにスマートポインターを使用することです。
スマートポインタとは何ですか?いつ使用する必要がありますか?

于 2012-04-30T22:05:01.593 に答える
1

これ:

MyClass test(0, TEXT("TEST"), 0);

自動オブジェクトを宣言します。
オブジェクトがスコープ外になると、オブジェクトは破棄されます。

{
   MyClass test(0, TEXT("TEST"), 0);   // constructed here
}                                      // destructed here.
于 2012-04-30T22:45:37.143 に答える
1

私はこれが古いスレッドであることを知っていますが、将来誰かを助けることができるなら、コピーコンストラクターが定義されていないときにこの投稿のコードをテストする同じ問題を見ました:https ://www.viva64.com/en/w / v690 /

1 raise                                    0x7ffff4e320e0
2 abort                                    0x7ffff4e336c1
3 __libc_message                           0x7ffff4e75427
4 malloc_printerr                          0x7ffff4e7bc43
5 MyArray::Clear         mainwindow.cpp 50 0x4204a5
6 MyArray::~MyArray      mainwindow.cpp 53 0x4204e2
7 MainWindow::MainWindow mainwindow.cpp 73 0x41416b
8 main                   main.cpp       10 0x40c372

そして、あなたのコードでは、コピーコンストラクターが次のようにヘッダーを定義していることがわかります。

MyClass::MyClass(const MyClass &);

単純にではなく:

MyClass(const MyClass &);

コピーコンストラクターが適切に宣言され、使用されているかどうかはわかりません。

とにかく、現在のGCCバージョンでは、「メンバー'MyArray[-fpermissive]のextraqualification' MyArray ::'」エラーのために合格しないため、この特定のケースは発生しないはずですが、コピーコンストラクターが欠落しているユーザーには役立ちます。

于 2019-12-06T10:29:12.200 に答える