4

这里有一个简单的问题,我的代码中有几个类,但只有一个表现出这个问题,我一生都无法弄清楚为什么。当我创建类的实例时,析构函数被立即调用,但类的实例实际上并没有被删除。

如果在析构函数中没有删除 [] 操作会影响类的实例,也许我可以忍受。

我在某处读到了“三法则”之类的东西,所以试图看看我错过了什么。我已经有一个默认构造函数以及一个用户定义的构造函数。然后我添加了我认为所谓的复制构造函数,如下所示:

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

一个可能的问题(但我们需要了解更多)是您的复制构造函数执行卷影复制,并且您从临时构造对象复制构造。当临时对象被销毁时,临时对象持有的内存被释放,新对象现在拥有已删除内存的指针。

一种解决方案是:在复制构建时执行深层复制。
http://www.learncpp.com/cpp-tutorial/912-shallow-vs-deep-copying/

另一个是:使用智能指针而不是原始指针。
什么是智能指针,我应该什么时候使用它?

于 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] 上的额外限定 'MyArray::'”错误而通过,但它可以帮助缺少复制构造函数的人。

于 2019-12-06T10:29:12.200 回答