讨论 一个有关构造函数和析构函数的问题??

xklc 2002-10-11 03:06:02
我有一个程序,代码如下.
#include <iostream.h>
#include <string.h>

class Person
{
public:
Person()
{
}
Person(const Person &p)
{
pName = p.pName;
}
Person(char* pN)
{
cout << "Constructing " << pN << endl;
pName = new char[strlen(pN)+1];
if (pName != 0 )
{
strcpy(pName, pN);
}
}
~Person()
{
if(pName != NULL)
{
cout << "Destructing " << pName << endl;
delete pName;
pName = NULL;
}
}
protected:
char *pName;
};

void main()
{
Person p1("Randy");
Person p2(p1);
}
程序在退出后,输出结果本来应该是:
Constructing Randy
Destructing Randy
Destructing Randy
但是我在vc6.0(win2000平台)下调试,出现的结果却是内存报错.不知道什么原因,请各位指教
...全文
96 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
yitong111 2002-10-12
  • 打赏
  • 举报
回复
if (pName != 0 )
{
strcpy(pName, pN);
pName[strlen(pN)+1]=NULL;
}
这样才行啊,你没有给字符串尾赋空值,当然会出现内存错误了
你要注意strlen不会给字符串尾自动加NULL的
hello_wyq 2002-10-11
  • 打赏
  • 举报
回复
这么多 的错误啊。

好好看书吧!

bugfree 2002-10-11
  • 打赏
  • 举报
回复

char *pName
改为
char pName[20];
sandrowjw 2002-10-11
  • 打赏
  • 举报
回复
默认的拷贝构造函数是二进制拷贝,由于你这里有指针,拷贝的时候把指针的值拷贝过去了,等于p1和p2的pNname指向同一个字符串,所以和原来的做法没有区别了。
bugfree 2002-10-11
  • 打赏
  • 举报
回复
没有给pName分内存
char *pName;
blh 2002-10-11
  • 打赏
  • 举报
回复
默认构造函数会创建一个块内存空间给新类,并且作一个类似memcpy的操作,将类的变量值进行复制,所以pName的指挥相同
鸵鸟 2002-10-11
  • 打赏
  • 举报
回复
#include <string.h>

class Person
{
public:
Person()
{
}
Person(const Person &p)
{
pName = p.pName; //error ,最好看看怎样写copy constructor
}
Person(char* pN)
{
cout << "Constructing " << pN << endl;
pName = new char[strlen(pN)+1];
if (pName != 0 )
{
strcpy(pName, pN);
}
}
~Person()
{
if(pName != NULL)
{
cout << "Destructing " << pName << endl;
delete pName; //error,用new [],动态分配的内存,请用delete []销毁.
pName = NULL;
}
}
protected:
char *pName;
};

void main()
{
Person p1("Randy");
Person p2(p1);
}
xklc 2002-10-11
  • 打赏
  • 举报
回复
To blh: 那为什么p2的pName为什么和p1的pName指向同一个地址呢.
blh 2002-10-11
  • 打赏
  • 举报
回复
默认构造函数有不会帮助你分配那个pName内存空间,回去好好看看c++的书再说
LinuxPanther 2002-10-11
  • 打赏
  • 举报
回复
是你的构造函数太简单了,让你的两个对象共享了一块内存,而在推出主函数是有调用两次析构函数,是你的第三次输出有错误可以改为:
#include<process.h>
class Person
{
...
Person(const Person &p)
{

pName = new char[strlen(p.pName)+1];
if (pName != 0 )
strcpy(pName, p.pName);
else
{
cout<<"Unseccess"<<endl;
exit(0);
}
cout<<"Person::copyconstructionfunction"<<pName<<endl;

}
........
};
xklc 2002-10-11
  • 打赏
  • 举报
回复
谢谢各位的解答,请看下面的程序,跟这个比较类似:
#include <iostream.h>
#include<string.h>

class Person
{
public:
Person(char* pN)
{
cout << "Constructing " << pN << endl;
pName = new char[strlen(pN)+1];
if (pName != 0 )
{
strcpy(pName, pN);
}

}
~Person()
{
cout << "Destructing " << pName << endl;
if(pName != NULL)
{
delete pName;
pName = NULL;
}
}
protected:
char *pName;
};

void main()
{
Person p1("Randy");
Person p2(p1);
}

本来我希望程序的运行结果是:
Constructing Randy
Destructing Randy
Destructing
但是依然是内存报错,本来, 在这部分中,没有拷贝构造函数,则应该调用默认的构造函数,因此当p2进行析构时,输出的结果应该是Destructing才对.但这里依然不对.请指教
kof99th 2002-10-11
  • 打赏
  • 举报
回复
楼上几位已经很清楚了。
使用指针一定要注意指针所指的内存空间,由谁分配,由谁释放,不难的。
hhdsq 2002-10-11
  • 打赏
  • 举报
回复
//下面这条语句出问题了
pName = p.pName;

经过这样的赋值以后,p1和p2的pName都指向同一块地址,在程序结束的时候析构了两次,当然会出错了。。

解决方法是利用strcpy,而不是用=来赋值
blh 2002-10-11
  • 打赏
  • 举报
回复
Person(const Person &p)
{
pName = p.pName; //这里的错误,这只是将p.pName和pName 指向同一块地址空间,并不是你本来认为的自动开辟一块新空间,呵呵,


if(pName != NULL)
{
cout << "Destructing " << pName << endl;
delete pName; //由于上面的错误,导致连续两次删除同一个地质,不错才怪呢,呵呵
pName = NULL;
}
blue_coco 2002-10-11
  • 打赏
  • 举报
回复
第二个构造函数有点问题。只是将指针付值,
相当于两个变量共用同一buffer.


Person()
{
pName = NULL
}
Person(const Person &p)
{
if (this == &p)
{
return;
}
if(NULL != pName)
{
delete pName;
}

pName = new char[strlen(p.pName)+1];
if (pName != 0 )
{
strcpy(pName, p.pName);
}
}

Person(char* pN)
{
cout << "Constructing " << pN << endl;
if(NULL != pName)
{
delete pName;
}

pName = new char[strlen(pN)+1];
if (pName != 0 )
{
strcpy(pName, pN);
}
}

70,024

社区成员

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

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