簡體   English   中英

C++ 類析構函數在構造函數之后直接調用

[英]C++ class destructor called straight after constructor

這里有一個簡單的問題,我的代碼中有幾個類,但只有一個類出現了這個問題,我一生都無法弄清楚原因。 當我創建一個類的實例時,析構函數被直接調用,但類的實例實際上並沒有被刪除。

如果析構函數中沒有 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

當對象被銷毀時應該調用析構函數。 如果使用new創建對象,則在對對象調用delete時會調用析構函數。 否則,它應該在超出其范圍時被調用。 您可以在其析構函數中設置斷點並查看調用堆棧以檢查調用析構函數的內容。 希望能幫助到你。

[更新] 嘗試為所有 ctor 和 dtor 添加以下printf以確保您不會與臨時創建的對象混淆。

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

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

[更新]

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

這會創建一個臨時對象作為 stl 容器(如vector )總是“復制”要存儲的東西。 (除非“移動”發生。我不想在這里開始解釋“移動”和右值。)

這:

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

聲明一個自動對象。
當對象超出范圍時,該對象將被銷毀。

{
   MyClass test(0, TEXT("TEST"), 0);   // constructed here
}                                      // destructed here.

一個可能的問題(但我們需要了解更多)是您的復制構造函數執行了影子復制,而您從臨時對象構造了對象復制構造。 當臨時被銷毀時,臨時持有的內存被釋放,新對象現在在已刪除的內存上有指針。

一種解決方案是:在復制構造時執行深復制。
http://www.learncpp.com/cpp-tutorial/912-shallow-vs-deep-copying/

另一個是:使用智能指針而不是原始指針。
什么是智能指針,什么時候應該使用?

我知道這是一個舊線程,但如果它可以幫助將來的某個人,當未定義復制構造函數時,我在這篇文章中測試代碼時看到了同樣的問題: 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]”上的“額外限定 'MyArray::'”錯誤而通過,但它可以幫助缺少復制構造函數的人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM