构造和析构函数.pptx_第1页
构造和析构函数.pptx_第2页
构造和析构函数.pptx_第3页
构造和析构函数.pptx_第4页
构造和析构函数.pptx_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、class Student public: void p(void); float score; protected: char *name; int age; ; Student a; Student a=5.5,“abcds”,6; a.age=6;(相当于) /非public;复杂,第五章:构造、析构函数,class Student public: void p(void); float score=5.5; protected: char *name=abcds; int age=6; ;,class Student public: void begin( ); 构造函数的最初设想 f

2、loat score; protected: char *name; int age; ; void student:begin() age=25; socre=80.5; name=zhang; Student a; a.begin();,构造、析构函数,class Student public: Student(); /构造函数的实现;系统约定与类同名;自动调用 int p(); protected: char *name; int age; ; Student:Student() /没有返回类型;特殊的成员函数 age=5; name=zhang ;/可以有参数,可以重载 Int stu

3、dent:p() return(age); Student a; couta.p();,构造、析构函数,class Student public: Student(); / 构造函数的声明,没有返回值,可以重载 Student(); / 析构函数的声明 ;没有参数; ,没有返回值,不可以重载 protected:/对象生命期结束时由系统自动调用 char *name; int age; ; Student:Student() age=5; Student:Student() cout“对象结束了; int main() Student a; Student b; return 0; /析构函数

4、的调用顺序和对象构造的顺序相反,析构函数不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作。还可以用来执行用户希望在对象生命期结束时所执行的任何操作。,class Student public: void Student(); /错误 void Student();/错误 protected: char *name; int age; ; void Student:Student()/错误 age=5; void Student:Student()/错误 cout“对象结束了”; Student a;,构造、析构函数,class Student public: Student(); S

5、tudent(); protected: char *name; int age; ; Student:Student() age=5; Student:Student() cout“对象结束了”; Student a; a.Student(); /错误 a.Student(); /不提倡,C+标准程序库中的string类 string name; 自动处理空间的占用问题。 可以用 = 进行赋值操作,= 进行比较,+ 做串联. 使用时#include /注意这里不是string.h string str1,str2=“abcd”; str1=str2; str2=str1+”123”; cou

6、tstr2 str2.length() str2.insert(0,8); 由C+字符串得到对应的C_string的方法是使用data()、c_str() data()以字符数组的形式返回字符串内容,但并不添加0。 char s20;strcpy(s,str1.data(); c_str()返回一个以0结尾的字符数组,strcpy(s,str2.c_str();,/带参数的构造函数 #include #include using namespace std; class Student public: Student(string pName, int i,float j) cout 构造学生

7、 pName endl; name = pName; semesHours=i; gpa=j; Student() cout 析构 name endl; /其它公共成员 private: string name; int semesHours; float gpa; ;,void f() Student t(Tom, 17, 90); int main() Student ss(Jenny, 20, 80.5); f(); return 0; ,class A public: int s; ; A a1; 对于没有显性构造函数的类系统都自动提供一个默认构造函数 A( ) 用户没有定义析构函数,

8、编译器自动生成一个析构函数。 A() ,构造、析构函数,/构造函数重载 class Student public: Student(string pName) cout 姓名 pName endl; name = pName; Student(string pName,int i) cout“姓名学时endl; name = pName; semesHours=i; private: string name; int semesHours; ; int main() Student tt(Tom,60); Student ss(Jenny); Student f; /错误 ? return 0

9、; ,如果手工定义了任何的构造函数,系统不再提供默认的无参构造函数。,/构造函数重载 class Student public: Student(string pName) cout 姓名 pName endl; name = pName; Student(string pName,int i) cout“姓名学时endl; name = pName; semesHours=i; Student() protected: string name; int semesHours; ; void main() Student tt(Tom,60); Student ss(Jenny); Stude

10、nt f; /不错误,构造、析构函数,自定义无参构造函数将替代缺省构造函数的存在,/默认值构造函数 改写重载构造函数 class Student public: Student(string pName=“”,int i=0) cout“姓名学时endl; name = pName; semesHours=i; protected: string name; int semesHours; ; int main() Student tt(Tom,60); Student ss(Jenny); Student f; /不错误 return 0; ,构造、析构函数,Student f(); Stu

11、dent g(int);声明函数 无名对象(一次性对象): Student(Jane) ; 一般作为实参,用在创建后不需要反复使用的场合。,构造函数是特殊的类成员函数。 C+规定与类同名的成员函数是构造函数,在该类的对象创建时,自动被调用。 构造函数负责对象的初始化 可拥有多个参数。可以重载。 构造函数不返回具体的值,不指定函数的返回类型。 可内置定义,也可以在类外定义。 通常是Public的,析构函数也是一个特殊的成员函数; 作用与构造函数相反;在对象的生命期结束时自动被调用。 名字是类名前加一个; 不返回任何值;没有函数类型,没有函数参数,因此不能被重载。 一个类可以由多个构造函数,只能有

12、一个析构函数。 可内置定义,也可以在类外定义。 用于清理和释放资源的工作。 通常是Public的,class A public: int s; private: A()coutA is constructingn; A()coutAn; ; int main() A s; /出错 return 0; /构造函数 semesHours=100; gpa=3.5; Student()cout“Studentn”; protected: int semesHours; float gpa; ; class Teacher public: Teacher( ) cout constructing te

13、acher.n; Teacher()cout“Teachern”; private: char name20; ;,/构造函数执行顺序 class TutorPair public: TutorPair() cout constructing tutorpair.n; noMeetings=0; /不可以访问Studnet和Teacher成员 TutorPair()cout“TutorPairn”; protected: Student student; Teacher teacher; int noMeetings; ; int main() TutorPair tp; cout back

14、in main.n; return 0;/类的工作过程中,分工十分明确,每个类只负责初始化它自己的对象。,/组合类对象的初始化困惑 class StudentID public: StudentID(int id=0) value=id; StudentID() protected: int value; ; class Student public: Student(string pName=noName,int ssID=0) name pName; private: string name; StudentID id ;,int main() Student s(Randy,9818);

15、 return 0;,类成员定义时不允许初始化, 因为类仅仅是一个类型, 而没有空间分配,(ssID); /错误,/组合类的构造函数如何工作 class StudentID public: StudentID(int id=0) value=id; StudentID() protected: int value; ; class Student string name; StudentID id; public: Student(string pName=noName,int ssID=0) name pName; StudentID id(ssID); /达不到效果 ;,int main(

16、) Student s(Randy,9818); return 0;,只是产生了临时变量,/组合类的构造函数如何工作 class StudentID public: StudentID(int id=0) value=id; StudentID() protected: int value; ; class Student string name; StudentID id; public: Student(string pName=“noName”,int ssID=0):id(ssID) name pName; ;,int main() Student s(Randy,9818); ret

17、urn 0;,冒号语法 用冒号引出构造函数的调用表(初始化列表) 用构造参数列表中说明的参数去调用构造函数,/例题(上)(s) class Student int semesHours; float gpa; public: Student(int i) cout constructing student.n; semesHours=i; gpa=3.5; Student()cout“Studentn”; ; class Teacher string name; public: Teacher(string p) name p; cout constructing teacher.n; Tea

18、cher()cout“Teachern”; ;,/例题(下)构造函数执行顺序(s) class TutorPair public: TutorPair(int i,int j,string p):teacher(p),student(j) /不影响构造函数调用顺序 cout constructing tutorpair.n; noMeetings=i; TutorPair()cout“TutorPairn”; protected: Student student; Teacher teacher; int noMeetings; ; int main() TutorPair tp(5,20,”

19、Jane”); cout back in main.n; return 0; ,noMeeting(i),/构造函数初始化常数据成员和引用成员 引用应依附于另一个独立的变量,等待初始化。 常量数据成员是仅仅初始化一次,其值便不再改变的数据成员。 二者只能借助冒号语法初始化。 class Student public: Student(int s,int ,构造、析构函数,int main() int c=123; Student s(9818,c); s.p(); return 0; ,对象构造顺序(s),局部和静态局部对象(文件作用域)以文本定义顺序为顺序, (类成员属于此种情况),静态对象

20、在首次定义时构造一次;程序结束析构,全局对象在main之前构造;程序结束时析构,全局对象如果分布在不同文件中,则构造顺序随机,class A public: A(int k)s=k; coutkA is constructingn; A()coutsAn; int s; ; int main() coutmain is runningn; A s(1); void f(); f(); f(); return 0; void f() coutf is runningn; A s(2); static A t(3); A t(4);,构造、析构函数(s),局部对象的构造:控制线程每次通过对象的定义

21、时,执行其构造函数。 所有函数之外定义的对象,在main()函数被激活之前初始化。,/全局对象的构造(s) A.h class A public: A(int r=0)s = r; private: int s; ; B.h class B public: B(A t)x = t; private: A x; ;,l.cpp #include “A.h” A h(6); void f() ; ,z.cpp #include “A.h” #include “B.h” extern A h; B k(h);/? int main() ; /全局变量构造顺序不确定,为对象申请动态空间: Malloc

22、 和对应的free函数不能调用构造函数和析构函数,这破坏了:空间分配、初始化的功能。所以引入了new和delete。 因为空间不确定才使用堆空间;是大多数情况 函数内部的申请空间要及时释放,否则容易造成内存重复申请和内存迷失;,class aa public: aa(int a=1)id=a; int id; aa()coutid; aa *q=(aa *)malloc(sizeof(aa); coutid;/随机数 表明构造函数未调用 delete p; free(q);/析构函数未调用 return 0;,构造、析构函数,class aa public: aa(int a=1)id=a;

23、int id; ; aa ,构造、析构函数,class aa public: aa(int a=1)id=a; int id; ; aa ,堆空间不伴随函数动态释放, 程序员要自主管理,构造、析构函数,class aa public: aa(int a=1)id=a; int id; aa()cout“aa is completed.”; ; void p() aa *s=new aa9999; int main() for(;) p(); return 0; /内存将被耗尽,构造、析构函数,class aa public: aa(int a=9)age =new inta; int * ag

24、e; ; int main() aa * s = new aa; s-age0 = 20; int * t = s-age; delete s; coutt0; return 0;,构造、析构函数,aa()delete age;,/析构函数的需要性,/对象数组(s) class Student public: Student() cinvalue; Student() coutvalueendl; protected: int value; ; int main() Student *p=new Student5; cout“Delete Begin”endl; delete p; retur

25、n 0; ,对象数组不能通过参数传递初始化。要么默认构造函数,要么构造函数有默认参数。 Student a10(20); /错误,/建立动态数组(s) int nextStudentID=1; class StudentID public: StudentID() value= nextStudentID + ; StudentID() -nextStudentID; protected: int value; ; class Student public: Student(string pName=noName) name pName; protected: string name; Stu

26、dentID id;,int main() int i, j; string temp; cini; Student *p=new Student * i ; for(j=0;jtemp; pj=new Student(temp); cout=0;j-) delete pj; delete p; coutnextStudentID; return 0; ,int i;int ai;/error int i; cini; int* p=new int i; deletep;,对象的赋值: class Student string name; int semesHours; public: Stu

27、dent(string pName=“”,int i=0) name=pName; semesHours=I; ; Student a(jenny,50); Student b; b=a; 一个已知对象赋值给另一个已知对象。 通过对赋值运算符的重载实现的。,对象的复制(拷贝):用一个已知对象构造(初始化)一个新对象。 例:一个对象构造(初始化)另一对象 Student s1(“Jenny”); Student s2=s1;即Student s2(s1); Student fn(Student s)Student k;/. ;return k void main() Student m,n; n

28、=fn(m); 使用Student (char* )不再合适,引入新的构造函数拷贝构造函数: Student (Student,/默认拷贝构造函数 /默认赋值运算符(函数) class Student public: Student(int k):i(k) Student () void p()coutiendl; protected: int i; ;/一旦显性给出 默认不再提供,构造、析构函数,int main() Student s(9818); s.p(); Student t(s); t.p(); Student m; m=t;/赋值 m.p(); return 0; ,/拷贝构造函

29、数 class Student public: Student(int k):i(k) Student () Student(Student const ,构造、析构函数,int main() Student s(9818); s.p(); Student t(s); t.p(); Student k=s; k.p(); Student *p=new Student(s); /也调用拷贝构造 p-p(); Student m; m=s; /调用赋值运算 m.p(); return 0; ,构造、析构函数,class aa public: aa()f=new char10; aa()delete

30、 f; char * f; ; int main() aa p; strcpy(p.f,Computer); coutp.fendl; aa q(p); / aa q=p; coutq.fendl; strcpy(p.f,“Software); coutq.fp.fendl; return 0;,创建q时, 对象p被复制给了q, 但资源未复制, 使得p和q指向 同一个资源, 这称为浅拷贝。,同一个指针执行两遍delete操作,会发生什么? 灾难,可能会破坏该堆及自由内存表,class aa public: aa()f=new char10; aa(aa const ,深拷贝,构造、析构函数,#

31、include using namespace std; class Student public: Student(int i) value=i; coutStudentvalueendl; Student()coutStudentvalueendl; protected: int value; ; int main() Student(9);/ 无名对象 ,正确 Student *p= ,构造、析构函数(s),Student9 Student9 Student8 Student8 Student7 Student6 Student5 Student5 Student5 Student7,构

32、造、析构函数,class aa public: aa(int a=1)id=a;cout“构造”endl; aa (aa ,类型转换,class aa public: aa(int a=1)id=a; char * p; int id; ; void m(aa a) couta.idendl; int main() m(9); /相当于m(aa(9); return 0; /如果存在m(int)的函数则优先匹配,类型转换,构造、析构函数,class aa public: aa(int a=1)id=a; int id; ; class bb public: bb(int a=2)id=a; int id; ; void m(aa a) couta.idendl; voi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论