C++程序设计教程修订版 第14章 堆与拷贝构造函数
- 格式:ppt
- 大小:192.50 KB
- 文档页数:34


student.h#ifndef STUDENT_H#define STUDENT_Hclass Student{public:Student(char* pName="no name",int ssID=0);Student(Student& s);//拷贝构造函数~Student();protected:char name[40];int id;};#endifstudent.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 studentRandycalling fn()constructing copy of RandyIn functiong fn()destructingcopy ofRandy//fn()函数结束,发生析构,析构的是fn中s对象returned from fn()constructing copy of Randy//拷贝构造jenny对象destructingcopy ofRandy//析构jenny对象destructingRandy//析构了randy对象没有拷贝构造函数:constructing new studentRandycalling fn()In functiong fn()//当没有自定义拷贝构造函数时,C++会调用默认的拷贝构造函数//但类拥有资源时,采用默认的拷贝构造函数容易出问题destructingRandy//fn()函数,发生析构,析构对象sreturned from fn()destructingRandy//析构对象jennydestructingRandy用一个类对象区构造一个新的对象时,如果没有自定义的拷贝构造函数,C++会调用默认的拷贝构造函数,但如果构造函数中有资源(堆内存)时,会出问题,因为默认的拷贝构造函数只会简单的拷贝资源,而不会分配资源,这时会出现:两个对象都拥有同一个资源的局面,在析构时会产生错误。
C++拷贝(复制)构造函数详解⼀. 什么是拷贝构造函数⾸先对于普通类型的对象来说,它们之间的复制是很简单的,例如:[c-sharp]1. int a = 100;2. int b = a;⽽类对象与普通对象不同,类对象内部结构⼀般较为复杂,存在各种成员变量。
下⾯看⼀个类对象拷贝的简单例⼦。
[c-sharp]1. #include <iostream>2. using namespace std;3.4. class CExample {5. private:6. int a;7. public:8. //构造函数9. CExample(int b)10. { a = b;}11.12. //⼀般函数13. void Show ()14. {15. cout<<a<<endl;16. }17. };18.19. int main()20. {21. CExample A(100);22. CExample B = A; //注意这⾥的对象初始化要调⽤拷贝构造函数,⽽⾮赋值23. B.Show ();24. return 0;25. }运⾏程序,屏幕输出100。
从以上代码的运⾏结果可以看出,系统为对象 B 分配了内存并完成了与对象 A 的复制过程。
就类对象⽽⾔,相同类型的类对象是通过拷贝构造函数来完成整个复制过程的。
下⾯举例说明拷贝构造函数的⼯作过程。
[c-sharp]1. #include <iostream>2. using namespace std;3.4. class CExample {5. private:6. int a;7. public:8. //构造函数9. CExample(int b)10. { a = b;}11.12. //拷贝构造函数13. CExample(const CExample& C)14. {15. a = C.a;16. }17.18. //⼀般函数19. void Show ()20. {21. cout<<a<<endl;22. }23. };24.25. int main()26. {27. CExample A(100);28. CExample B = A; // CExample B(A); 也是⼀样的29. B.Show ();30. return 0;31. }CExample(const CExample& C) 就是我们⾃定义的拷贝构造函数。
默认拷贝构造函数
1 拷贝构造函数
拷贝构造函数是 C ++ 中重构语言特性之一,它用来拷贝一个对
象到另一个对象,从而实现了对象的复制。
例如,一个基类可以拷贝
到子类,而不是使用的子类的构造函数,以实现”父子”的拷贝构造
函数。
在 C++ 中,拷贝构造函数是一种特殊的函数,它由编译器自动生成。
对对象及其子对象/部分进行浅拷贝,而不是全部拷贝。
默认情况下,编译器会为每个类生成一个无参的拷贝构造函数,也可以加入自
定义的拷贝构造函数,它可以完成深度拷贝。
拷贝构造函数有四种使用情况:当一个对象直接或间接初始化为
另一个对象;当对象赋值给另一个对象;当一个对象被压入一个容器;当一个对象从一个容器取出。
由于它的默认构建函数行为,可以使用
默认的拷贝构造函数和赋值运算符在不同的类之间的简单的实例赋值。
拷贝构造函数也有一些缺点。
由于它只是对对象及其子对象/部分
进行浅拷贝,它只能在表面上复制,而不能实现真正的拷贝,所以无
法处理复杂数据类型。
当类中存在指针拷贝时,拷贝构造函数也存在
一些问题,因为一个指针拷贝另一个指针,并不能实现真正的拷贝,
而只是拷贝一个指针的值。
总而言之,拷贝构造函数是 C++ 中重要的特性,它在默认模式下可以使用简单的实例赋值,但也存在其自身的一些局限性,一些复杂数据类型和指针拷贝时存在许多问题,应该避免使用。
C++编程析构函数拷贝构造函数使⽤⽰例详解⽬录构造函数析构函数拷贝构造之深拷贝和浅拷贝深浅拷贝区别⾸先定义⼀个类进⾏操作。
class MM{public:protected:int year;string name;}构造函数在类中默认有⼀个⽆参的构造函数默认的构造函数为类名(){};这个构造函数如果直接写了构造函数那么这个构造函数将会没有构造函数class MM{public://MM() {};//⽆参构造函数MM(int year, string name) :year(year), name(name) {};//有参构造函数在定义对象的时候必须传参数,没参数会报错MM(int year, string name){this->name = name;this->year = year;}//这两个是⼀样的MM(int year, string name = "") :year(year) {};//因为string 是缺省的如果写没有构造默认为空就是 MM mm(15);这⾥mm对象year=15 name=“”;//缺省只能左边到右边protected:int year;string name;};析构函数MM(){};就是对构建的对象进⾏销毁析构函数的使⽤是⼀个⾃动调⽤的过程不需要⼈为进⾏,当对象的⽣命周期结束⾃动释放//析构函数需要注意的点1.当对象存在指针的时候使⽤析构函数时,析构函数⾥⾯需要释放指针的指向class MM{public:MM(const char* str){strcpy(this->str, str);}~MM() { delete[] str; };//这⾥需要释放str内存不然析构函数只会释放类不会释放strprotected:int year;string name;char* str;};int main(){MM mm("kkk");return 0;}如果类中没有指针就不⽤在析构函数中去释放指针指向拷贝构造(对对象进⾏赋值)//直接调⽤拷贝构造不调⽤构造函数MM mm(15,"kkk");//拷贝构造的⼆种⽅式对对象进⾏赋值MM mm1(mm);MM mm2 = mm;mm1.printfMM();mm2.printfMM();如果是通过匿名创建时匿名对象调⽤构造函数MM mm3 = MM(16, "jfsdl");mm3.printfMM();然后匿名对象赋值给对象调⽤的是拷贝构造函数拷贝构造之深拷贝和浅拷贝//浅拷贝默认也是浅拷贝就是赋值拷贝MM(const MM&object){this->str = object.str;}//深拷贝//深拷贝就是通过指针申请指向然后进⾏赋值MM(const MM& object){int len = strlen(object.str) + 1;this->str = new char[len];strcpy(str, object.str);}深浅拷贝区别浅拷贝就是进⾏了赋值操作深拷贝是通过申请指针后再进⾏赋值(深拷贝析构函数要释放申请的指针)谢谢⼤家的阅读,如有不⾜请及时指出,万分感激以上就是C++编程析构函数拷贝构造函数使⽤⽰例详解的详细内容,更多关于C++编程析构函数拷贝构造函数的资料请关注其它相关⽂章!。