请大家帮我看一下这题!!!(拷贝构造函数)

ra3 2002-11-22 01:07:06
(VC6编译)
运行时结果也对,会出一个调试出错的对话框。

如果不释放分配的堆内存,则没事。

在拷贝构造函数中我已经给成员 pName 分配了堆内存了,应该不会再共用一段内存。即使先调用 deleteName(); 函数释放原有的堆内存也不行。
/////////////////////////////////////////////////////////////////////
#include <iostream.h>
#include <string.h>

class CName
{
public:
CName(){pName=NULL;}
CName(char *pn){copyName(pn);}
CName(CName& s){copyName(s.pName);} //拷贝构造函数
~CName(){deleteName();}
void display();

protected:
void copyName(char *pn);
void deleteName();

protected:
char *pName;
};

void CName::display()
{
cout<<pName<<endl;
}

void CName::copyName(char *pn)
{
pName=new char[strlen(pn)+1];
if(pName) strcpy(pName,pn);
}

void CName::deleteName()
{
if(pName)
{
delete[] pName;
pName=NULL;
}
}

void main()
{
CName s("claudette");
CName t("temporatry");
t.display();
t=s;
t.display();
}

...全文
37 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dynamic 2002-11-22
  • 打赏
  • 举报
回复
#include <iostream.h>
//#include <string.h>这句不需要!

class CName
{
public:
CName():pName(NULL){}
CName(char *pn):pName(NULL){copyName(pn);}//一定要初始化

pName!
CName(CName& s){copyName(s.pName);}
~CName(){deleteName();}
CName& operator=(const CName&);//重载运算符
void display();

protected:
void copyName(char *pn);
void deleteName();

protected:
char *pName;
};

void CName::display()
{
if(pName)cout<<pName<<endl;
}

void CName::copyName(char *pn)
{
deleteName();//这句话防止内存泄漏!
pName=new char[strlen(pn)+1];
if(pName)strcpy(pName,pn);//要防止new操作符失败!
}

void CName::deleteName()
{
if(pName)
{
delete[] pName;
pName=NULL;
}
}

CName& CName::operator=(const CName& s)//重载运算符
{
if (this == &s) return *this;
copyName(s.pName);
return *this;
}

void main()
{
CName s("claudette\0");//不加\0,strcopy会出错!
CName t("temporatry\0");//不加\0,strcopy会出错!
s.display();
t.display();
t=s;
t.display();
}
//另外程序应当注意写作风格!
ice_river_feng 2002-11-22
  • 打赏
  • 举报
回复
同意楼上所说的。

需要重载操作符: “="
CName& CName::operator =(CName &rhs)
{
if (this == &rhs)
return *this;

if (pname)
{
delete[] m_pname;
m_pname= 0;
}

int nLen = rhs.GetLength(); //统计pname字节数的函数,可以自己写的)
if (nLen>0)
{
pname = new char[nLen+1];
memset(m_szBuf, 0, nLen+1);

strcpy(pname, (LPCTSTR)rhs);
}
else
{
pname = 0;
}

return *this;
}

inline CName::operator LPCTSTR ( ) const
{
return pname;
}
asiaas 2002-11-22
  • 打赏
  • 举报
回复
好像是
t=s;
“=”需要重载
bugfree 2002-11-22
  • 打赏
  • 举报
回复
Your code need do the following modification:
1.
//t=s; ====> t(s); // you can modify your code as this way.

2. Please add deleteName() to your copyName func, as following:

/////////
void CName::copyName(char *pn)
{
delete[] pName;
pName=new char[strlen(pn)+1];
if(pName) strcpy(pName,pn);
}
muche 2002-11-22
  • 打赏
  • 举报
回复
上面说的对,你的程序造成了两个指针指向同一内存区域,然后又被两次释放,肯定会出问题的!
zxm954712 2002-11-22
  • 打赏
  • 举报
回复
一下为我改过的:
#include <iostream.h>
#include <string.h>

class CName
{
public:
CName(){pName=NULL;}
CName(char *pn){copyName(pn);}
CName(CName& s){copyName(s.pName);} //拷贝构造函数
CName & operator =(const CName &s);
~CName(){deleteName();}
void display();

protected:
void copyName(char *pn);
void deleteName();

protected:
char *pName;
};

CName & CName::operator =(const CName &s)
{
if (this == &s) return *this;

deleteName();

copyName(s.pName);
return *this;
}

void CName::display()
{
cout<<pName<<endl;
}

void CName::copyName(char *pn)
{
pName=new char[strlen(pn)+1];
if(pName) strcpy(pName,pn);
}

void CName::deleteName()
{
if(pName)
{
delete[] pName;
pName=NULL;
}
}

void main()
{
CName s("claudette");
CName t("temporatry");
t.display();
t=s; //赋值
t.display();
}
里面没有用到拷贝构造函数啊,要写一个赋值函数才行啊,如果不写的话,则编译器调用缺省的函数,会进行位的拷贝,这样s 和t里面的pName会指向同一块内存区,一来内存泄漏(t中的pName内存没被释放),二来在s和t的pName指向的内存区域释放了两次,当然会内存报错了。呵呵,而且你的拷贝构造函数也要先释放原来的内存,不然也会内存泄漏啊。呵呵
lx_cyh 2002-11-22
  • 打赏
  • 举报
回复
t=s;会有问题
只会把s.pName复制给t.pName,两者指向同一块空间(这样t.pName原来的空间丢失),最后析构时两次释放同一空间,因而出错
解决的办法是重载=运算符

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧