c++中构造函数和析构函数

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
void main() { Point p1 , p2(1,2); p1.print(); p2.print(); } 主函数能否增加: Point p3(); p3.print();
10.1 构造函数
10.1.6 构造函数和new运算符
1. 用new运行符产生动态对象 (1)产生单个对象(可以初始化); (2)产生数组对象(不能初始化)。 如: class C { float r,i; public: C (float r1 ,float i1){ r=r1; i=i1; cout<<“构造\n”; } C (){ r=i=0; cout<<“缺省构造\n”; } }; void main() { C *p1=new C,*p2=new C (2,-3), *p3=new C[5]; }
10.1 构造函数
10.1.4 构造函数产生对象 建立对象时,必须提供与构造函数形参一致的实参,其 基本格式只有如下两种形式:
类名 对象名(实参); 类名 对象名; 例10-2 用例10-1定义的类定义对象,并初始化。 class Point{ 主函数中,能否添加下列语句: float x,y; Point p3; public: Point(float a,float b); Point(float a) { x=y=a;} void print(){ cout<<„(„<<x<<„,‟<<y<<“)\n”; } }; Point:: Point(float a,float b) { x=a; y=b; } void main(){ Point p1(5),p2(10,15); p1.print();p2.print(); }
2. 定义后赋值 (1)用成员函数赋值----回顾第9章示例3; (2)用同类型的对象赋值。 如:class A{ public: int a,b; void set(int x,int y){a=x;b=y;} }; void main() { A a1={5,10},a2,a3; a2.set(15,20); a3=a1;}
10.2 析构函数
1. 析构函数的概念 用于撤消对象的成员函数。
2. 定义格式 (1)类中定义 ~类名() { ... } //函数体 (2)类中说明,类外定义 ① 类中说明 ~类名();//类中说明 ② 类外定义 类名::~类名()//类外定义 { ... } //函数体
10.2 析构函数
3. 使用时注意: (1)析构函数的名称由运算符‘~‟与类名组成;
10.4 构造函数和对象成员
1. 对象成员的概念 类的数据成员为其他已定义类的对象,该成员称为对象成员。
2. 初始化对象成员的方法 在构造函数中以对象名调用对象所属类的构造函数完成,其基 本格式为: 类名::类名(形参表):对象名(实参表) { …… }//初始化普通成员 3. 当前对象在初始化(构造函数调用)时的顺序 (1)先完成对象成员的初始化,有多个对象成员时,先说明的 先初始化; (2) 再完成普通成员的初始化。 即先调用对象成员所属类的构造函数,再执行自身类的函数体。 4. 对象的撤消(析构函数调用)顺序:与建立顺序相反。
}
对象说明顺序 决定构造函数 调用顺序 对象调用构造 函数语句决定 对象成员的值
课堂练习
一、选择题
1、以下有关析构函数的叙述不正确的是 。 A、析构函数没有任何函数类型 B、析构函数的作用是在撤销对象时收回分配的内存空间 C、析构函数可以有形参 D、一个类只有一个析构函数 2、关于类的缺省构造函数,下列说法正确的是 。 A、类的缺省构造函数没有参数 B、类的缺省构造函数是由系统自动产生的空函数 C、每个类均可定义缺省的构造函数 D、每个类均有且有一个缺省的构造函数 3、通常拷贝初始化构造函数的参数是 。 A、某个对象的名称 B、某个对象的成员名 C、指向某个对象的指针名 D、某个对象的引用名
10.1 构造函数
10.1.5 缺省ห้องสมุดไป่ตู้构造函数
1. 缺省构造函数的种类 (1)系统自动产生的构造函数,如下所示: 类名(){ } (2)用户定义的没有参数的构造函数; (3)用户定义的所有参数都有缺省值的构造函数。
2. 用缺省构造函数创建对象的格式:类名 对象名;
3. 使用时的注意 (1)只有在用户没有定义构造函数时,系统才自动产 生构造函数; (2)类中可能没有缺省的构造函数; (3)一个类最多只能有一个缺省的构造函数。
class Point{ float x,y; public: Point(float a,float b); Point(float a) { x=y=a;} void print() { cout<<„(„<<x<<„,‟<<y<<“)\n”; } }; Point:: Point(float a,float b) { x=a; y=b; }
10.1 构造函数
例10-3 缺省构造函数的使用。 class Point{ float x,y; 能否对A行作如下修改? public: Point( ) { x=0; y=0; } Point(float a =0 ,float b =0 ) { x=a; y=b; }//A void print(){ cout<<„(„<<x<<„,‟<<y<<“)\n”; } };
Visual C++程序设计
第10章
构造函数 和析构函数
第10章 构造函数和析构函数
10.1 构造函数 10.2 析构函数 10.3 实现类型转换和 拷贝的构造函数
10.4 构造函数和对象成员
10.1 构造函数
给对象的数据成员赋值有二类(四种)方法: 1. 定义时赋值(初始化) (1)用数据列表初始化(数据成员为公有访问权限); (2)用构造函数初始化。
10.4 构造函数和对象成员
例10-7 含对象成员类的构造函数。 class A{ int a; public: A(int x=0) { a=x; cout<<“A()\n”; ~A() { cout<<a<<“~A()\n”; } }; class B{ int b; public: B(int x=0) { b=x; cout<<“B()\n”; } ~B () { cout<<b <<“~B()\n”;} }; class C{ int c; B b1; A a1; B b2; public: C(int x,int y,int z):a1(x),b1(y),b2(z) { c=x+y+z; cout<<“C()\n”; } ~C() { cout<<c <<“~A()\n”; } }; void main(){ C c1(1,2,3); }
10.3 实现类型转换和拷贝的构造函数
10.3.2 完成拷贝功能的构造函数
拷贝功能的构造函数实现:用一个已建立的对象初始化同类型 的对象,其调用格式为:
类名 新对象名(已建立对象名); 或 类名 新对象名=已建立对象名; x=5,10, 普通构造 例10-5 用拷贝构造函数初始化对象。 x=5,10, 拷贝构造 class Ex{ int x,y; x=5,10, 拷贝构造 public: Ex(int a,int b) { x=a; y=b; cout<<“x=”<<x<<“,y=”<<y<<“,普通构造。\n”; } Ex(Ex &t)//拷贝功能的构造函数 {x=t.x; y=t.y; cout<<“x=”<<x<<“,y=”<<y<<“,拷贝构造。\n”; } }; void main() { Ex e1(5,10); Ex e2(e1); Ex e3=e2; }
(2)析构函数无函数类型,无参数,且不返回值; (3)析构函数不可以重载,每个类只有一个析构函数; (4)类中通常不需要定义析构函数,而由系统自动产生 一个如下的缺省析构函数: 类名::~类名(){ } (5)当类中用new 运算符分配了动态空间时,必须定义 析构函数,并在函数体中用delete运算符释放动态空间。 4. 构造函数与析构函数的调用过程 在创建对象时,调用构造函数;在撤消对象时,调用析 构函数;所以它们的调用过程(顺序)通常是相反的。
10.1 构造函数
10.1.1 构造函数的概念 1. 构造函数是实现数据成员初始化的特殊的成员函数; 2. 构造函数与类同名,没有类型,也不返回值; 3. 创建对象时,构造函数被自动调用。每创建一个对象 都必须调用一次构造函数,每调用一次构造函数必定创 建一个对象。 10.1.2 构造函数的种类 1. 普通构造函数:普通参数; 2. 拷贝构造函数:参数为对象的引用。 一个类至少有上述两个构造函数,可以有更多的构造 函数(构造函数允许重载),以实现不同形式对象的创 建。
10.1 构造函数
2. 用new为指针成员分配动态空间 当类的数据成员为指针时,在构造函数中应: ·先用new运算符为指针动态分配空间; ·然后再对指针所指空间赋值。
如: class Array { int*p; ...}; //p表示10个元素的一维数组 则如下的构造函数都是错误的: Array(int *t){p=t;} Array (int *t){*p=*t;} Array (int *t){for(int i=0;i<10;i++)p[i]=t[i];} Array (int *t){p=new int[10]; p=t;} // *p=*t; 正确的应为: Array (int *t){ p=new int[10]; // 分配动态空间 for(int i=0;i<10;i++)p[i]=t[i]; // 对动态空间赋值 }
10.3 实现类型转换和拷贝的构造函数
10.3.1 实现类型转换的构造函数
当一个对象被赋值为一个数字,如果这个数字可以放入某个构 造函数实现对这个构造函数的调用时,则该赋值语句成立。其实质 是以所给的数据为参数调用普通的构造函数初始化对象,此时的构 造函数称为类型转换的构造函数。 例10-4 用类型转换的构造函数初始化对象。 x=5,y=10 class Ex{ int x,y; x=15,y=10 public: x=20,y=10 Ex(int a, int b=10) 20,释放对象。 { x=a; y=b; cout<<“x=”<<x<<“,y=”<<y<<“\n”; } End. ~Ex(){ cout<<x<<“,释放对象。\n”;} 其中: 15,释放对象。 }; 20,释放对象。 Ex e2=15;等同于 Ex e2(15); e1=20;等同于e1=Ex(20); void main() { Ex e1(5); Ex e2=15; e1=20; cout<<“End.\n”;}
10.1 构造函数
10.1.3 构造函数的定义
1. 类中定义格式 类名(形参列表) { ... } //函数体,对数据成员赋值 2. 类中说明,类外定义
(1) 类中说明
类名(形参列表); (2)类外定义 类名::类名(形参列表) { ... } //函数体
10.1 构造函数
例10-1 定义表示平面点的类Point及其构造函数。
情况下必须重新定义:
(1)新建对象与已建立对象的数据有差异;如:Ex2 e2(e1); (2)数据成员中有指针,并使用了动态内存。

类的构造函数有两类、多种形式,使用时应加以区分。
10.3 实现类型转换和拷贝的构造函数
例10-6 用普通构造函数和拷贝构造函数创建对象。 class A { public: 运行结果: A(int x=1){cout<<x<<“\t”;} 1 2 3 A(A&t){cout<<“拷贝\t”;} 4 拷贝 拷贝 拷贝 }; 5 0 void main() { A a1,a2(2),a3=3;cout<<„\n‟; A a4=A(4),a5=a1,a6(a1); cout<<„\n‟; a1=5; a2=a1; 程序中共创建了几个对象? a3=A(0); cout<<„\n‟; }
10.3 实现类型转换和拷贝的构造函数

与普通构造函数相似,若用户不定义拷贝功能构造函数,系
统自动产生一个缺省的拷贝功能构造函数,它把已建立对象 各数据成员的值依次赋给新对象。其定义如下: 类名::类名(类名 &对象名){ *this=对象名; }

用户通常可以直接使用缺省的拷贝功能构造函数,但在以下
相关文档
最新文档