第八章 类和对象(二)

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

1-2

构造函数概述
② 有参构造函数: 格式:类名(类型 1 形参1,类型2 形参2,…) {初始化成员代码} 说明:构造函数的实参是在定义对象时给出的
public: Complex(double real,double image) { m_real = real; m_real; m_imag; } m_imag = image; double double
2-2
对象指针
指向对象成员函数的指针 成员函数与普通函数有一个最根本的区别: 它是类中的一个成员。编译系统 要求在赋值语句中,指针变量的类型必须与赋值号右侧函数的类型相匹配,要 求在以下3方面都要匹配:
① 函数参数的类型和参数个数;
② 函数返回值的类型; ③ 所属的类。
2-2
对象指针【例8-7】
//将对象t1的数据成员hour的地址赋给p1 //输出t1.hour的值
说明:
① 指向类中数据成员的指针变量不是类中的成员,这种指针变量应在类外定义。 ② 与指向类中数据成员的指针变量同类型的任一数据成员,可将其地址赋给这种指针变量,赋 值的一般格式为:PointName = &ClassName::member;这种赋值,是取该成员相对于该类 的所在对象中的偏移量,即相对地址(距离开始位置的字节数) ③ 用这种指针访问数据成员时,必须指明是使用那一个对象的数据成员。当与对象结合使用时, 其用法为: ObjectName.* PointName
1-2
构造函数概述
构造函数是一种特殊的公有的成员函数。主要用来在创建对象时初始化对象, 即为对象数据变成员初始值。【例8-1】
数据成员可以通过对象初始化完成,为什么还需要构造函数?
如果一个类中的数据成员是私有的,或者有private或protected的成员,就不能采用对
象的初始化方法
1-2
构造函数概述
构造函数的特点
构造函数的命名必须和类名完全相同 构造函数不具有任何类型,没有返回值。 构造函数不能直接调用,而是在建立对象时自动执行
构造函数是类的成员函数,具有一般成员函数的所有性质,可访问类的所有成员
1-2
构造函数概述
注意:
全局对象和静态对象的构造函数在main()函数执行之前就被调用,局部静态对象的构造函数是 当程序第一次执行到相应语句时才被调用。然而给出一个外部对象的引用性声明时,并不调用 相应的构造函数,因为这个外部对象只是引用在其他地方声明的对象,并没有真正地创建一个 对象。
注意:
类的数据成员是不能在声明类时初始化的。 如果一个类中所有的数据成员都是公用的,则可以在定义对象时对数据成员进行初始化。
class Time
{ public:
int hour; int minute; int sec;
};
Time t1={14,56,30}; //将t1初始化为14:56:30
第8章 类和对象(二)
1 2 3 4
构造函数与 析构函数 对象指针与 对象数组 类的共享 数据保护 对象的 高级应用
5 6
静态成员 友元
1-1
对象的初始化
在建立一个对象时,常常需要进行初始化,即对数据成员赋初值。如果一个数 据成员未被赋值,那么它的值是不可预知的,这显然与客观事物的属性不相符。
指向对象数据成员的指针 定义指向对象数据成员的指针变量和定义指向普通变量的指针变量方法相 同,其一般形式为:数据类型名 *指针变量名
假设“类Time”的数据成员hour为公用的整型数据 int *p1; //定义指向整型数据的指针变量
p1=&t1.hour;
cout<<*p1<<endl;
//将对象t1的数据成员hour的地址赋给p1
//输出t1.hour的值
2-2
对象指针【例8-7】
格式:<数据成员类型> 类名:: *指针名;
假设“类Time”的数据成员hour为公用的整型数据
int Time::*p1;
p1=&Time::hour; Time t1; cout<<t1.*p1<<endl;
//定义指向整型数据的指针变量
{
A a1,a2;//产生对象时自动调用缺省构造不赋值
a1.Set (2.0,4.0); cout<<"a1: “<<a1.x<<a1.y<<a1.sum(); cout<<“a2:"<<a2.x<<a2.y<<a2.Sum();
void Set(float a,float b) { x=a;y=b;}
}; }
//打印随机值
1-3
使用默认参数的构造函数【8-4】
构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,即如果用 户不指定实参值,编译系统就使形参取默认值。
说明:
① 应该在声明构造函数时指定默认值,或只在定义构造函数时指定默认值。
② 在声明构造函数时,形参名可以省略。
③ 如果构造函数的全部参数都指定了默认值,则在定义对象时可以给一个或 几个实参,也可以不给出实参。 ④ 在一个类中定义了全部是默认参数的构造函数后,不能再定义重载构造函 数。
在定义类时,若没有定义类的构造函数,则编译器自动产生一个缺省的构造函数 格式:类名::类名() { } 注意:缺省的构造函数并不对所产生对象的数据成员赋初值;即新产生对象的数据成员的值是
不确定的。
class A{ void main()
float x,y;
public: A(){ }//缺省构造函数,编译器自动产生,可以不写 float Sum() { return x+y; }
1-6
析构函数概述【例8-5】
析构函数(destructor)也是一个特殊的公有的成员函数,其作用与构造函数相 反,主要是:
在撤销对象占用的内存之前完成一些清理工作,使这部分内存可以被程序分配给新 对象使用。析构函数并不删除对象。 可以被用来执行“用户希望在最后一次使用对象之后所执行的任何操作”
① 定义指向成员函数的指针变量 格式:数据类型名 (类名::*指针变量名)(参数表列);
void (Time::*p2)( );//定义p2为指向Time类中公用成员函数的指针变量
Student Stud[3]={Student(1001,18,87), Student(1002,19,76), Student(1003,18,72)};
③ 如果类包含多个构造函数,则可以对不同的元素使用不同的构造函数
Student Stud[3]={Student(1001,18,87), Student(), Student(1003,18,72)};
1-6
析构函数概述
当一个类创建多个对象时,构造函数与析构函数的执行情况?
在使用构造函数和析构函数时,需要特别注意它们的调用时间和调用顺序。一般情况下, 调用析构函数的次序正好与调用构造函数的次序相反
2-1
对象数组【例8-6】
数组不仅可以由简单变量组成,也可以由对象组成 声明对象数组的方法与声明标准类型数组相同 在定义对象数组时,每一个数组元素即对象,都要调用构造函数。 对象数组可以进行初始化。
假定已定义一个“时间类Time”。 Time t1; Time *pt; pt=&t1; //定义t1为Time类对象 //定义pt为指向Time类对象的指针变量 //将t1的起始地址赋给pt
通过对象指针访问对象和对象的成员
*指针变量
(*指针变量).成员
指针变量->成员
2-2
对象指针【例8-ຫໍສະໝຸດ Baidu】
1-6
析构函数概述
析构函数的特点
一个类只能由一个析构函数 析构函数的名字是在类名的前面加一个“~”符号。 析构函数不具有类型,没有返回值,也没有函数参数,因此不能被重载。
如果用户没有定义析构函数,C++编译系统会自动生成一个析构函数,但它什么操作都不
进行。 析构函数是成员函数,函数体可写在类体内,也可写在类体外。
初始化对象数组的过程是首先使用默认构造函数创建数组元素,然后大括号中的构造函数将创
建临时对象,然后将临时对象的内容复制到相应的元素中。
2-2
对象指针【例8-7】
指向对象的指针
在建立对象时,编译系统会为每一个对象分配一定的存储空间,以存放其成员。对象空 间的起始地址就是对象的指针。可以定义一个指针变量,用来存放对象的指针。 格式:类名 *对象指针名;
① 如果类的构造函数只有一个参数,那么在定义数组时可以直接在等号后面的花括号内提 供实参。编译系统只为每个对象元素的构造函数传递一个实参。
Student stud[3]={60,70,78}; Student stud[3]={60,70,78,45}; //合法 //不合法
2-1
对象数组
② 如果类的构造函数有多个参数,应该分别调用构造函数,对每个元素初始化,即采用在 花括号中分别写出构造函数并指定实参的方法进行初始化。
1-6
析构函数概述
构造函数与析构函数的调用环境
如果在一个函数中定义了一个对象(自动局部对象),当该函数被调用时,对象自动调用构 造函数;当该函数被调用结束时,对象被释放,在对象释放前自动执行析构函数。 static局部对象当该函数被调用时,对象自动调用构造函数;在函数调用结束时对象并不 释放,因此不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用 static局部对象的析构函数。 如果定义了一个全局对象,在进入main函数前调用构造函数;则在程序的流程离开其作 用域时(如main函数结束或调用exit函数) 时,调用该全局对象的析构函数。 如果用new运算符动态地建立了一个对象,当用delete运算符释放该对象时,先调用该对 象的析构函数。
调用构造函数
C++提供了两种使用构造函数来初始化对象的方法
显示调用构造函数
Stock food=Stock("World Cabbage",250,1.25);
另一种是隐式地调用构造函数 Stock garment("Furry Mason",50,2.5); 构造函数的使用方式不同于其他类方法,无法使用对象来调用构造函数,因为在构造 函数构造出对象之前,对象是不存在的。因此构造函数被用来创建对象,而不能通过 对象来调用
class Complex { private :
1-2
构造函数概述
用参数初始化表对数据成员初始化【例8-2】
不在函数体内对数据成员初始化,而是在函数首部实现 格式:类名::类名(参数列表):数据成员1(参数1),数据成员2(参数2)...,数据成员n(参数n)
1-2
构造函数概述
缺省的构造函数
1-4
重载构造函数【例8-3】
在一个类中可以定义多个构造函数,这些构造函数具有相同的名字,而参数的 个数或参数的类型不相同。这称为构造函数的重载。
说明:在一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时 根据传入的参数不同调用不同的构造函数,并非每个构造函数都被执行。
1-5
指向对象成员函数的指针
格式:类名 *指针变量名
假设“类Time”的数据成员hour为公用的整型数据 Time *p1=&t1; //定义指向对象t1的指针变量
p1->gettime();
//调用gettime()成员函数
2-2
对象指针
定义指向对象成员函数的指针变量的方法和定义指向普通函数的指针变量方法 有所不同,分为两个步骤:
在构造函数的函数体中不仅可以包含与初始化有关的内容,即对数据成员赋初值,也可以包含
其他语句。 如果用户自己没有定义构造函数,则C++系统会自动生成一个构造函数,只是这个构造函数 的函数体是空的,也没有参数,不执行初始化操作
1-2
构造函数概述
构造函数的种类:
① 无参构造函数: 格式:类名(){初始化成员代码;} 说明:如果创建一个类没有任何构造函数,则系统会自动生成默认的无参构造函数,函数体为空
如果定义了某一种构造函数,系统就不会再自动生成这样一个默认的构造函数,如果希
望有一个这样的无参构造函数,则需要显示地定义 class Complex { private : public: Complex() { m_real = 0.0;
double
double
m_real;
m_imag; }
m_imag = 0.0;
相关文档
最新文档