堆与拷贝构造函数

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

student.h
#ifndef STUDENT_H
#define STUDENT_H
class Student
{
public:
Student(char* pName="no name",int ssID=0);
Student(Student& s);//拷贝构造函数
~Student();
protected:
char name[40];
int id;
};
#endif
student.cpp
#include <iostream>
#include <string>
#include "student.h"
using namespace std;
Student::Student(char* pName,int ssID)
{
strcpy(name,pName);
cout<<"constructing new student"<<pName<<endl;
}
Student::Student(Student& s)
//拷贝构造函数,必须用引用或指针,不能直接用student(student s) //因为不能像基本数据类型那样直接传递对象的值。

{
cout<<"constructing copy of"<<<<endl;
strcpy(name,"copy of");
strcat(name,);
id=s.id;
}
Student::~Student()
{
cout<<"destructing"<<name<<endl;
}
/*
*test.cpp
*堆与拷贝构造函数的测试
*2011/10/7
*刘珅珅
*/
#include <iostream>
#include <string>
#include "student.h"
using namespace std;
void fn(Student s);
int main(int argc,char* argv[])
{
Student randy("Randy",1234);
cout<<"calling fn()\n";
fn(randy);//要调用拷贝构造函数
cout<<"returned from fn()\n";
Student jenny=randy;//调用拷贝构造函数
return 0;
}
void fn(Student s)
{
cout<<"In function fn()\n";
}
输出的结果:
有拷贝构造函数:
constructing new studentRandy
calling fn()
constructing copy of Randy
In functiong fn()
destructingcopy ofRandy//fn()函数结束,发生析构,析构的是fn中s对象returned from fn()
constructing copy of Randy//拷贝构造jenny对象
destructingcopy ofRandy//析构jenny对象
destructingRandy//析构了randy对象
没有拷贝构造函数:
constructing new studentRandy
calling fn()
In functiong fn()
//当没有自定义拷贝构造函数时,C++会调用默认的拷贝构造函数
//但类拥有资源时,采用默认的拷贝构造函数容易出问题
destructingRandy//fn()函数,发生析构,析构对象s
returned from fn()
destructingRandy//析构对象jenny
destructingRandy
用一个类对象区构造一个新的对象时,如果没有自定义的拷贝构造函数,C++会调用默认的拷贝构造函数,但如果构造函数中有资源(堆内存)时,会出问题,因为默认的拷贝构造函数只会简单的拷贝资源,而不会分配资源,这时会出现:两个对象都拥有同一个资源的局面,在析构时会产生错误。

这时需要自定义拷贝构造函数做深拷贝。

person.h
#ifndef PERSON_H
#define PERSON_H
class Person
{
public:
Person(char* pN);
Person(Person& p);//拷贝构造函数
~Person();
protected:
char* pName;
};
#endif
person.cpp
#include <iostream>
#include <string>
#include "person.h"
using namespace std;
Person::Person(char* pN)
{
cout<<"constructing "<<pN<<endl;
pName=new char[strlen(pN)+1];
if(pName!=0)
{
strcpy(pName,pN);
}
}
Person::Person(Person& p)
{
/*
*这个拷贝构造函数是必须的,原因是析构函数中使用deltete将堆空间返回给系统
*如果没有拷贝构造函数,而使用默认的拷贝构造函数,那么后面的程序中p1,p2将拥有完全相同的堆空间,在析构时,析构了p2后,堆空间已经返回给系统,再析构p1时,执行delete pName;就会出错
*/
cout<<"Copying"<<p.pName<<"into its own block\n";
pName=new char[strlen(p.pName)+1];
if(pName!=0)
strcpy(pName,p.pName);
}
Person::~Person()
{
cout<<"destructing"<<pName<<endl;
pName[0]='\0';
delete pName;
}
test.cpp
/*
*test.cpp
*堆与拷贝构造函数的测试
*2011/10/7
*刘珅珅
*/
#include <iostream>
#include <string>
#include "person.h"
using namespace std;
int main(int argc,char* argv[])
{
Person p1("Randy");
Person p2=p1;//即Person p2(p1)
return 0;
}
堆内存并不是唯一一个需要拷贝构造函数的资源,打开文件,占有硬件资源都需要拷贝构造函数,很好的经验:
如果类需要析构函数来析构资源,则它也需要一个拷贝构造函数。

相关文档
最新文档