C++ 堆区类析构报错
本帖最后由 Eden00 于 2023-4-20 22:45 编辑补充,似乎问题出在继承,改变继承顺序后,就变成delete c0无法析构,是否有什么问题?
如下代码,没有报错,但是每次运行到delete v0;(157行)的时候,会报错Exception has occurred.Unknown signal,请问是为啥?
谢谢!
#include <iostream>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <ctime>
using namespace std;
class CPU
{
public:
string cname;
virtual void calculate() = 0;
~CPU()
{
cout << cname << " CPU is destructed" << endl;
}
};
class VideoCard
{
public:
string vname;
virtual void display() = 0;
~VideoCard()
{
cout << vname << " video card is destructed" << endl;
}
};
class Memory
{
public:
string mname;
virtual void store() = 0;
~Memory()
{
cout << mname << " memory is destructed" << endl;
}
};
class Supplier : public CPU, public VideoCard, public Memory
{
string name;
void calculate()
{
cout << name << " CPU is calculating" << endl;
}
void store()
{
cout << name << " memory is stoing" << endl;
}
void display()
{
cout << name << " video card is displaying" << endl;
}
public:
Supplier()
{
cout << "Supplier is structed without argument" << endl;
}
Supplier(string n) : name(n)
{
cout << "Supplier is structed with name as " << n << endl;
}
string SetName(string n)
{
cout << "Supplier name is set by Class Supplier as " << n << endl;
name = n;
return name;
}
string GetName()
{
return name;
}
~Supplier()
{
cout << name << " supplier is destructed" << endl;
}
};
class Computer
{
CPU *c0;
VideoCard *v0;
Memory *m0;
public:
Computer(Supplier c, Supplier v, Supplier m)
{
c0 = new Supplier(c);
v0 = new Supplier(v);
m0 = new Supplier(m);
c0->cname = c.GetName();
v0->vname = v.GetName();
m0->mname = m.GetName();
cout << "This computer is assembled with " << c0->cname << " CPU, " << v0->vname
<< " video card, " << m0->mname << " memory" << endl;
}
~Computer()
{
/* if (c0 != NULL)
{
cout << c0->cname << endl
<< c0 << endl;
delete c0;
c0 = NULL;
}*/
if (v0 != NULL)
{
cout << v0->vname << endl
<< v0 << endl;
delete v0;
v0 = NULL;
}
if (m0 != NULL)
{
delete m0;
m0 = NULL;
}
}
void work()
{
c0->calculate();
v0->display();
m0->store();
}
};
void fun0()
{
Supplier q0("Qualcom");
Supplier i0;
i0.SetName("Intel");
Supplier a0("AMD");
Computer c0(q0, i0, a0);
c0.work();
}
int main()
{
fun0();
system("pause");
return 1;
} Eden00 发表于 2023-4-20 22:32
经过我重新审查代码,找到了问题所在。问题出在析构函数的调用顺序。首先,`Computer`的析构函数被调用,接着调用`Supplier`的析构函数。但是在`Supplier`的析构函数中,由于它继承了`CPU`、`VideoCard`和`Memory`类,所以它们的析构函数也会被调用。因此,在`Computer`的析构函数中,我们需要确保在删除`c0`、`v0`和`m0`之前调用它们的析构函数。
为了解决这个问题,我们可以在`Supplier`类中添加一个名为`cleanUp`的函数,该函数在`Computer`的析构函数中调用,确保调用`CPU`、`VideoCard`和`Memory`的析构函数。
在`Supplier`类中添加`cleanUp`函数:
void cleanUp()
{
cname.clear();
vname.clear();
mname.clear();
}
在`Computer`类的析构函数中调用`cleanUp`函数:
~Computer()
{
if (c0 != NULL)
{
c0->cleanUp();
delete c0;
c0 = NULL;
}
if (v0 != NULL)
{
v0->cleanUp();
delete v0;
v0 = NULL;
}
if (m0 != NULL)
{
m0->cleanUp();
delete m0;
m0 = NULL;
}
}
现在,您的程序应该能够正常运行,不会报错。 根据您提供的代码,问题出在`Computer`类的构造函数中,您试图将已经构造的`Supplier`对象复制给`CPU`、`VideoCard`和`Memory`指针,这将导致析构时多次删除同一对象。为了解决这个问题,您可以将构造函数参数的类型改为指针,并在`main`函数中分配相应的对象。
首先,将`Computer`的构造函数参数类型更改为指针:
class Computer
{
CPU *c0;
VideoCard *v0;
Memory *m0;
public:
Computer(Supplier *c, Supplier *v, Supplier *m)
{
c0 = c;
v0 = v;
m0 = m;
c0->cname = c->GetName();
v0->vname = v->GetName();
m0->mname = m->GetName();
cout << "This computer is assembled with " << c0->cname << " CPU, " << v0->vname
<< " video card, " << m0->mname << " memory" << endl;
}
// ...其他成员函数不变
};
接下来,在`main`函数中分配相应的对象并传递指针:
void fun0()
{
Supplier *q0 = new Supplier("Qualcom");
Supplier *i0 = new Supplier;
i0->SetName("Intel");
Supplier *a0 = new Supplier("AMD");
Computer c0(q0, i0, a0);
c0.work();
}
int main()
{
fun0();
system("pause");
return 1;
}
最后,您需要更新`Computer`类的析构函数,以删除这些动态分配的`Supplier`对象。
~Computer()
{
if (c0 != NULL)
{
delete c0;
c0 = NULL;
}
if (v0 != NULL)
{
delete v0;
v0 = NULL;
}
if (m0 != NULL)
{
delete m0;
m0 = NULL;
}
}
这样修改后,您的程序应该不会再报错,并按预期运行。 isdkz 发表于 2023-4-20 22:05
根据您提供的代码,问题出在`Computer`类的构造函数中,您试图将已经构造的`Supplier`对象复制给`CPU`、`Vi ...
改了之后还是不行 本帖最后由 Eden00 于 2023-4-20 22:44 编辑
isdkz 发表于 2023-4-20 22:05
根据您提供的代码,问题出在`Computer`类的构造函数中,您试图将已经构造的`Supplier`对象复制给`CPU`、`Vi ...
#include <iostream>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <ctime>
using namespace std;
class CPU
{
public:
string cname;
virtual void calculate() = 0;
~CPU()
{
cout << cname << " CPU is destructed" << endl;
}
};
class VideoCard
{
public:
string vname;
virtual void display() = 0;
~VideoCard()
{
cout << vname << " video card is destructed" << endl;
}
};
class Memory
{
public:
string mname;
virtual void store() = 0;
~Memory()
{
cout << mname << " memory is destructed" << endl;
}
};
class Supplier : public CPU, public VideoCard, public Memory
{
string name;
void calculate()
{
cout << name << " CPU is calculating" << endl;
}
void store()
{
cout << name << " memory is stoing" << endl;
}
void display()
{
cout << name << " video card is displaying" << endl;
}
public:
Supplier()
{
cout << "Supplier is structed without argument" << endl;
}
Supplier(string n) : name(n)
{
cout << "Supplier is structed with name as " << n << endl;
}
string SetName(string n)
{
cout << "Supplier name is set by Class Supplier as " << n << endl;
name = n;
return name;
}
string GetName()
{
return name;
}
~Supplier()
{
cout << name << " supplier is destructed" << endl;
}
};
class Computer
{
CPU *c0;
VideoCard *v0;
Memory *m0;
public:
Computer(Supplier *c, Supplier *v, Supplier *m)
{
c0 = c;
v0 = v;
m0 = m;
c0->cname = c->GetName();
v0->vname = v->GetName();
m0->mname = m->GetName();
cout << "This computer is assembled with " << c0->cname << " CPU, " << v0->vname
<< " video card, " << m0->mname << " memory" << endl;
}
~Computer()
{
if (c0 != NULL)
{
cout << c0->cname << endl
<< c0 << endl;
delete c0;
c0 = NULL;
}
if (v0 != NULL)
{
cout << v0->vname << endl
<< v0 << endl;
delete v0;
v0 = NULL;
}
if (m0 != NULL)
{
delete m0;
m0 = NULL;
}
}
void work()
{
c0->calculate();
v0->display();
m0->store();
}
};
void fun0()
{
Supplier *q0=new Supplier("Qualcom");
Supplier *i0=new Supplier("Intel");
Supplier *a0=new Supplier("AMD");
Computer c0(q0, i0, a0);
c0.work();
}
int main()
{
fun0();
system("pause");
return 1;
}
isdkz 发表于 2023-4-20 23:38
经过我重新审查代码,找到了问题所在。问题出在析构函数的调用顺序。首先,`Computer`的析构函数被调用, ...
c0是CPU指针,v0是videocard指针按照定义应该不能调用supplier类的函数。
但是思路是对的,应该要确保supplier析构时,父类们也一起析构,因此感谢啦
页:
[1]