析构函数问题+列表显示[重复]
Posted
技术标签:
【中文标题】析构函数问题+列表显示[重复]【英文标题】:Destructor problems+ list display [duplicate] 【发布时间】:2016-02-07 00:05:30 【问题描述】:我有以下代码:
问题是当我在 main 类型中创建一个列表时:Reteta
。
显示列表后,我收到错误分配错误。如果我从 Reteta
类中评论析构函数,程序就可以工作。你能帮我找出错误吗?或者也许我没有很好地显示列表,所以程序还有其他问题需要处理。
代码如下:
#include<iostream>
#include<fstream>
#include<list>
using namespace std;
class Medicament
private:
char *denumire;
float pret;
public:
Medicament()
this->pret = 0;
this->denumire = new char[strlen("Fara denumire")];
strcpy(this->denumire, "Fara denumire");
Medicament(char* denumire, float pret)
this->denumire = new char[strlen(denumire) + 1];
strcpy(this->denumire, denumire);
this->pret = pret;
Medicament(const Medicament& x)
this->denumire = new char[strlen(x.denumire) + 1];
strcpy(this->denumire, x.denumire);
this->pret = x.pret;
~Medicament()
if (this->denumire)
delete[] this->denumire;
void setDenumire(char *x)
if (x)
if (this->denumire)
delete[] this->denumire;
this->denumire = new char[strlen(x) + 1];
strcpy(this->denumire, x);
char* getDenumire()
return this->denumire;
void setPret(float f)
if (f)
this->pret = f;
Medicament operator=(Medicament x)
this->denumire = new char[strlen(x.denumire) + 1];
strcpy(this->denumire, x.denumire);
this->pret = x.pret;
return *this;
friend ostream& operator<<(ostream& consola, Medicament &x)
consola << "Medicament: " << x.denumire << endl; //error here
consola << "Pret: " << x.pret << endl;
return consola;
float getPret()
return this->pret;
friend class Reteta;
;
class Reteta
protected:
Medicament *medicamente;
int n;
public:
Reteta()
this->n = 0;
this->medicamente = NULL;
Reteta(Medicament *v, int n)
this->n = n;
this->medicamente = new Medicament[n];
for (int i = 0; i < n; i++)
this->medicamente[i] = v[i];
~Reteta()
if (this->medicamente)
delete[] this->medicamente; //The problem is here. If I comment this the program works.
int getN()
return this->n;
friend ostream& operator<<(ostream& consola, Reteta& x)
consola << "Numar de medicamente: " << x.n << endl;
consola << " -->Lista Medicamente<-- "<<endl;
for (int i = 0; i < x.n; i++)
consola << x.medicamente[i].getDenumire() <<endl; //error at this line when I compile
consola << x.medicamente[i].getPret()<< endl;
return consola;
void adaugaMedicament(Medicament x)
Reteta y;
y.medicamente= new Medicament[this->n+1];
for (int i = 0; i < this->n; i++)
y.medicamente[i] = this->medicamente[i];
y.medicamente[this->n] = x;
delete[] this->medicamente;
this->medicamente = new Medicament[this->n + 1];
this->n++;
for (int i = 0; i < this->n; i++)
this->medicamente[i] = y.medicamente[i];
Medicament operator[](int i)
if (i >= 0 && i < this->n)
return this->medicamente[i];
friend class RetetaCompensata;
virtual float getValoare()
float sum = 0;
for (int i = 0; i < this->n; i++)
sum=sum+this->medicamente[i].getPret();
return sum;
friend ifstream& operator>>(ifstream& consola, Reteta& x)
char aux[30];
float z;
consola >> x.n;
if (x.medicamente)
delete[] x.medicamente;
x.medicamente = new Medicament[x.n];
for (int i = 0; i < x.n; i++)
consola >> aux >> z;
Medicament m(aux, z);
x.medicamente[i] = m;
return consola;
;
class RetetaCompensata : public Reteta
private:
float procentCompensat;
public:
RetetaCompensata(float procent)
this->procentCompensat = procent;
RetetaCompensata(Reteta r, float procent)
this->procentCompensat = procent;
this->n = r.n;
this->medicamente = new Medicament[r.n];
for (int i = 0; i < r.n; i++)
this->medicamente[i] = r.medicamente[i];
float getValoare()
float sum = 0;
sum = this->procentCompensat*this->getValoare();
return sum;
friend ostream& operator<<(ostream& consola, RetetaCompensata &x)
consola << "**Procent compensat: " << x.procentCompensat << endl;
consola << "Numar de medicamente: " << x.n << endl;
consola << " -->Lista Medicamente<-- " << endl;
for (int i = 0; i < x.n; i++)
consola << x.medicamente[i] << " ";
return consola;
;
void main()
//1
Medicament nurofen("Nurofen", 11.25f);
Medicament aspirina = nurofen;
aspirina.setDenumire("Aspirina");
aspirina.setPret(4.5f);
Medicament bixtonim("Bixtonim", 8.2f);
Medicament temp;
temp = nurofen;
cout << temp << endl;
cout << nurofen << endl;
cout << aspirina << endl;
//2
Medicament medicamente[] = aspirina, nurofen ;
Reteta r0(medicamente, 2);
cout << r0 << endl;
//3
Reteta r1;
r1.adaugaMedicament(nurofen);
r1.adaugaMedicament(aspirina);
for (int i = 0; i < r1.getN(); i++)
cout << r1[i] << endl;
//4
RetetaCompensata r2(0.5);
r2.adaugaMedicament(bixtonim);
r2.adaugaMedicament(aspirina);
RetetaCompensata r3(r1, 0.2);
cout << "AFISARE R3" << endl;
cout << r3 << endl << endl;
Reteta* p = &r1;
cout <<"Valoare reteta r1: "<< p->getValoare() << endl;
//5
Reteta r4;
ifstream fisier("retete.txt");
fisier >> r4;
cout << r4 << endl;
//6
cout << endl << "Afisare Lista :" << endl << endl << endl;
list<Reteta> R;
list<Reteta>::iterator it;
R.push_back(r0);
R.push_back(r1);
R.push_back(r3);
R.push_back(r2);
R.push_back(r4);
for (it = R.begin(); it != R.end(); it++)
cout << *it << " Valoare Reteta: " << it->getValoare() << endl << endl << endl; // error at this line when I compile
【问题讨论】:
Medicament operator=(Medicament x)
赋值运算符应该返回一个引用,而不是一个新对象。为什么不使用std::string
而不是char *
?单独这样做会削减您编写的代码的主要部分。
我是新手。我必须这样做。几周后我将只玩 STL。
应该是相反的。现在使用 STL,稍后使用指针(很久以后)。
当您的类在构造函数中分配内存并在析构函数中释放内存时,您必须正确实现复制构造函数和复制赋值运算符。
嗯..您使用的是std::list
而不是std::string
?说真的,如果您使用 std::string
而不是 char *
和 std::vector<Medicament>
而不是 new Medicament[n]
,那么所有这些代码都可以工作。
【参考方案1】:
这是内存覆盖:
this->denumire = new char[strlen("Fara denumire")];
strcpy(this->denumire, "Fara denumire");
您没有为终止空字符分配空间:
this->denumire = new char[strlen("Fara denumire") + 1];
strcpy(this->denumire, "Fara denumire");
但是,当您有 std::string
可用时,为什么要这样做呢?仅此一项不仅可以缓解此类错误,而且您无需为 Medicament
类编写赋值运算符、复制构造函数或析构函数。
另一个错误是您的Reteta
类缺少复制构造函数和赋值运算符,因此由于Medicament*
成员,它不能安全地复制。然后,您将此类用作std::list<Reteta>
中的类型。
由于Reteta
不能安全地复制,而std::list
进行复制,因此您进入了未定义行为的世界。因此,您必须为Reteta
类提供适当的复制/赋值运算符。
【讨论】:
责备我的老师 :)) 在 30 小时内我在 PO 进行了期末考试。所以我们不得不使用 *char 等。STL 就像考试的 10%。那么错误是什么?如果我从 Reteta 类中删除析构函数,它就可以工作.. 第 116 行和第 265 行是问题 “由于 Reteta 不是安全可复制的,并且 std::list 进行复制,因此您进入了未定义行为的世界。因此您必须为 Reteta 类提供适当的复制/赋值运算符。”这是我的问题。我创建了这些运算符并开始工作。谢谢你的时间保罗!以上是关于析构函数问题+列表显示[重复]的主要内容,如果未能解决你的问题,请参考以下文章