第八章 类与对象 本章要求: 掌握类的含义与定义格式。 掌握类的无参构造函数、带参构造函数、拷贝构造函数和赋值重载函数的定义格式及作用。

Slides:



Advertisements
Similar presentations
实数与代数式是初中数学中重要的基础知识, 是中考的必考内容.这部分知识散布于多个章节之中, 知识点琐碎,但概念性强,在中考试卷中多以填空题、 选择题、化简、探索或求值的形式出现.在复习中, 一定要加强对各个概念、性质和公式的辨析和理 解.注重让学生在实际背景中理解基本的数量关系和 变化规律,注重使学生经历从实际问题中建立数学模.
Advertisements

第四章 类、对象和接口.
专题17:一次函数.
第一节 人口的数量变化.
德 国 鼓 励 生 育 的 宣 传 画.
第四章:长期股权投资 长期股权投资效果 1、控制:50%以上 有权决定对方财务和经营.
人民版必修三专题三复习 近代中国 思想解放的潮流 灵石中学 易吉华.
高考图表题及常考题型解题策略与复习建议 晋江市季延中学 吴梅德 2016年12月30日.
第8课 列方程(组)解应用题.
22.3 实际问题与一元二次方程(1).
合 同 法 主讲人: 教材:《合同法学》(崔建远) 2017/3/10.
不会宽容人的人, 是不配受到别人的宽容的。 贝尔奈.
复习回顾 a a×a a×a×a a a×a×a= a×a= 1.如图,边长为a厘米的正方形的面积 为 平方厘米。
中考数学的解题技巧 ——选择题专题.
第三讲 匀变速直线运动 学 科:物 理 主讲人:吴含章. 第三讲 匀变速直线运动 学 科:物 理 主讲人:吴含章.
第一单元 人在社会中生活 综合探究一 从地图上获取信息 第1课时 带着地图定向越野间.
第九讲 类与对象 (I)面向对象基础.
第6章 多态性与虚函数.
第四章 时间序列的分析 本章教学目的:①了解从数量方面研究社会经济现象发展变化过程和发展趋势是统计分析的一种重要方法;②掌握时间数列编制的基本要求;③理解和掌握水平速度两方面指标的计算及运用④理解和掌握长期趋势分析和预测的方法。 本章教学重点:现象发展的水平指标和速度指标。 本章教学难点:现象变动的趋势分析。
第5节 关注人类遗传病.
遗传系谱题的分析与解法 江苏省仪征中学 生物组.
類別與物件 Class & Object.
C++语言程序设计教程 第7章 类与对象 第7章 类与对象.
Chapter 5 利率的風險結構與期間結構. Chapter 5 利率的風險結構與期間結構.
复习与总结.
走向C++之路 WindyWinter WindyWinter感谢诸位前来捧场。
西安交通大学 计算机教学实验中心 大学C++程序设计教程 西安交通大学 计算机教学实验中心
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Object-Oriented Programming in C++ 第一章 C++的初步知识
程序设计期末复习 黎金宁
第三章 C++中的C 面向对象程序设计(C++).
如何寫工程計畫書 臺北市童軍會考驗委員會 高級考驗營 版.
C++语言程序设计教程 第7章 类与对象 第7章 类与对象.
第二章 C++对C 在非面向对象方面的改进 更简洁,更安全.
类类型 C++支持的内置类型和操作,如 int i=10; i=i%6; i=i+4;
导数及其应用 高三数学组 葛乃兵.
第十章 模板 丘志杰 电子科技大学 计算机学院 软件学院.
第一模块 向量代数与空间解析几何 第四节 平面及其方程 一、平面的点法式方程 二、平面的一般方程 三、两平面的夹角.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
第七章 操作符重载 胡昊 南京大学计算机系软件所.
第12讲 多继承与虚基类 多继承 虚基类.
C语言复习3----指针.
C#程序设计基础 $3 成员、变量和常量.
第16章 数据的共享和流通 一、浅拷贝和深拷贝 二、只读成员函数 三、友元friend.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
第10讲 构造函数和析构函数 构造函数 析构函数 This 指针.
電子白板百萬小學堂 本活動建議搭配電子白板 學生最多可分成2~6組(請按組別按鈕) 老師可以視時間多少,來進行活動 每一組要回答十個問題。
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
C++大学基础教程 第10章 运算符重载 北京科技大学 2019/5/7 北京科技大学.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
面向对象技术 练习 ffh.
THE C PROGRAMMING LANGUAGE
C++程序设计基础 主讲人:谢昕 华东交通大学信息工程学院 第十~十二讲 多态性和虚函数 2005年春季学期.
本节内容 对象拷贝 视频提供:昆山爱达人信息技术有限公司.
本节内容 引用类型 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第 9 章 建構函式與解構函式.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
#include <iostream.h>
第四章 函数 丘志杰 电子科技大学 计算机学院 软件学院.
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
Class 2005/05/25.
第三章 高级函数特性.
§12-5 同方向同频率两个简谐振动的合成 一. 同方向同频率的简谐振动的合成 1. 分振动 : 2. 合振动 : 解析法
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
本节内容 在堆中创建对象 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第9章 C++程序设计初步 9.1 C++的特点 9.2 最简单的C++程序 9.3 C++的输入输出 9.4 函数的重载
C++程序语言设计 Chapter 14: Templates.
第二章 Java基础语法 北京传智播客教育
2.2.2双曲线的简单几何性质 海口市灵山中学 吴潇.
Presentation transcript:

第八章 类与对象 本章要求: 掌握类的含义与定义格式。 掌握类的无参构造函数、带参构造函数、拷贝构造函数和赋值重载函数的定义格式及作用。 第八章 类与对象 本章要求: 掌握类的含义与定义格式。 掌握类的无参构造函数、带参构造函数、拷贝构造函数和赋值重载函数的定义格式及作用。 掌握类的构造函数中初始化表的使用格式及功能。 掌握析构函数的定义格式与功能。 了解友元函数和友元类的声明与作用。

8.1 类的定义 类是对具有共同属性和行为的一类事物的抽象描述

8.1 类的定义 共同属性被描述为类中的数据成员 共同行为被描述为类中的成员函数 脊椎动物共同的属性:脊椎(长度、节数等) 8.1 类的定义 共同属性被描述为类中的数据成员 脊椎动物共同的属性:脊椎(长度、节数等) 鸟类的共同属性:翅膀(长度、羽毛等) 共同行为被描述为类中的成员函数 爬行动物共同的行为:爬行 猫科动物共同的行为:奔跑、捕食

8.1 类的定义 同结构和联合一样,类也是一种用户定义的类型,它包括定义数据成员和定义成员函数两个方面,用数据成员来描述同类事物的属性,用成员函数来描述他们的行为。 类是抽象的,不是实际存在的,既不占据存储 对象是具体的,象是类的实例化,是实际存在的,占据存储。

8.1 类的定义 8.1.1 类的定义格式 基本格式: class <类名> {<成员表>}; class为类类型定义的关键字, 8.1 类的定义 8.1.1 类的定义格式 基本格式: class <类名> {<成员表>}; class为类类型定义的关键字, <类名>为用户命名的标识符,用它可以定义该类的对象以及对象的引用、对象指针和对象数组。 <成员表>为该类包含的数据成员和成员函数的列表,每一个成员都具有一定的存取权限(或称访问权限),成员的存取权限是由存取指明符关键字public,private或protected所指定。

8.1 类的定义 8.1.1 类的定义格式 三个存取指明符的含义如下: public:公用访问属性,成员可以为任意函数所使用。 8.1 类的定义 8.1.1 类的定义格式 三个存取指明符的含义如下: public:公用访问属性,成员可以为任意函数所使用。 private:私有访问属性,成员只能为该类的成员函数和友元函数所使用。 protected:保护访问属性,成员只能为该类的成员函数和友元函数以及派生类中的成员函数和友元函数所使用。 说明:若成员定义的前面没有使用存取指明符规定存取权限,则类成员的访问属性默认为private,对于结构和联合成员的访问属性默认为public

8.1 类的定义 8.1.2 定义格式举例 1:struct CA { int a; int b; } ax; 2: class CB{ 8.1 类的定义 8.1.2 定义格式举例 1:struct CA { int a; int b; } ax; 2: class CB{ int a; } bx; 3:class CC { int a; public: void init(int aa) { a=aa; } int GetData() { return a;} }cx;

8.1 类的定义 8.1.2 定义格式举例 5. class CE {private: int a,b; 8.1 类的定义 8.1.2 定义格式举例 5. class CE {private: int a,b; int getmax() {return(a>b? a:b);} public: int c; void setvalue(int ,int ,int ); int getmax() {int d=getmax(); return (d>c? d:c); } }; void CE::setvalue(int x1,int x2,int x3) {a=x1; b=x2; c=x3;} … … CE ex,*ep=&ex; 4. class CD { char* a; int b; public: void init( char* aa,int bb) {a=new char[strlen(aa)+1]; strcpy(a,aa); b=bb; } char* geta(){return a;} int getb() {return b;} void output() {cout<<a<<‘ ‘<<b<<endl;} }dx;

8.1 类的定义 8.1.3 有关说明 类中的成员函数和数据成员一样,都是在给定类中定义的,必须通过对象(包括直接对象和指针对象)调用成员函数。 在一个类的成员函数中,能够直接使用该类定义的所有数据成员和成员函数,其使用表示也是抽象的,因为并没有将它们同任何一个类对象具体联系起来。 一个类的每个成员函数中都隐含有一个所属类的指针参数,其名字由系统规定为this,它是一个c++关键字,this指针指向调用该成员函数的对象。

8.1 类的定义 8.1.3 有关说明 成员函数可以在类中给出定义;也可以使成员函数的声明和定义分开,即只在类中给出声明,而在类外给出完整的定义,这样做可以避免类体过于冗长。 成员函数同普通函数一样,也可以通过使用inline关键字把它定义为内联函数。若成员函数是在类中定义的,则隐含为内联的。 同普通函数一样,每个成员函数中说明的形参也允许带有默认值。

8.1 类的定义 8.1.3 有关说明 每个类类型的大小,即由该类定义的对象所占用存储空间的字节数等于所有数据成员所占存储字节数的总和。 8.1 类的定义 #include<iostream.h> class Time { private: int h,m,s; public: void SetTime(int,int,int); void DisplayTime() { cout<<h<<":"<<m<<":"<<s<<endl;} }; void Time::SetTime(int initH,int initM,int initS) { h=initH; m=initM; s=initS;} void main() Time t; t.SetTime(9,25,45); t.DisplayTime(); } 运行结果: 9:25:45 8.1.3 有关说明 每个类类型的大小,即由该类定义的对象所占用存储空间的字节数等于所有数据成员所占存储字节数的总和。 同普通函数一样,类中的成员函数也允许函数名重载和操作符重载。 例:定义一个时间类Time,能够表示时、分、秒组成 的时间和设置、显示时间,并编写应用程序,定 义时间对象,设置、输出该对象的时间。 例:(P237)

8.2 构造函数 构造函数和析构函数属于类中的成员函数。 8.2 构造函数 构造函数和析构函数属于类中的成员函数。 构造函数与所在的类具有相同的名字,并且不带任何返回类型,也不需要返回任何值,函数的参数表和函数体由用户根据需要编写,是否为一个类建立重载的多个构造函数,也由用户根据使用类的需要而定。 构造函数的作用是建立对象,为类对象中的数据成员赋初值,有时还为其中的指针数据成员动态分配所指向的存储空间。 构造函数是在建立对象时自动调用的,而不允许像其他成员函数那样由用户直接调用。 因为建立对象都是在类外进行的,必须把每个构造函数定义为类的公用成员。

8.2 构造函数 8.2.1 无参构造函数和带参构造函数 当定义一个类时,若没有定义构造函数,则系统隐含定义一个无参构造函数,该构造函数的函数体也为空,调用系统所给的构造函数不会执行任何操作,只是建立对象。 类定义中的无参构造函数可能是系统定义的(用户未定义任何构造函数时),也可能是用户定义的,但带参构造函数必定是由用户定义的。 当用类类型定义一个类对象时,若需要它自动调用无参构造函数对其进行初始化,则只需给出对象名,若需要它自动调用带参构造函数对其进行初始化,则给出的对象名后必须带有用圆括号括起来的实参表。

8.2 构造函数 8.2.2 拷贝构造函数 类中的构造函数当有并且只有一个所属类的引用参数时,则称此构造函数为拷贝构造函数或复制构造函数。 8.2 构造函数 #include<iostream.h> class A { public: A( );//声明无参构造函数 A(int,int=0);//声明有参构造函数 A(A&);//声明拷贝构造函数 private: int a,b; }; A::A( )//定义无参构造函数 { a=0;b=0; cout<<"Constructor!"<<endl; } A::A(int initA,int initB)//定义有参构造函数 { a=initA;b=initB; cout<<"Constructor:"<<a<<','<<b<<endl; A::A(A&x)//定义拷贝构造函数 { a=x.a;b=x.b; cout<<"Copying Constructor:"<<a<<','<<b<<endl; void main(){ A m(2);//调用有参构造函数一次 A *p=new A[2];//调用无参构造函数2次 A n(m);//调用拷贝构造函数一次 8.2.2 拷贝构造函数 类中的构造函数当有并且只有一个所属类的引用参数时,则称此构造函数为拷贝构造函数或复制构造函数。 当用一个类对象初始化同类的另一个对象时需要调用相应的拷贝构造函数。 若一个类中不带有拷贝构造函数,则系统为该类隐含定义一个拷贝构造函数。 X(X& x) { *this=x; //将引用形参的值赋给被初始化的对象 } 例:构造函数、拷贝构造函数举例。

8.2 构造函数 #include<iostream.h> #include<string.h> class A { public: A(char*);//声明构造函数 A&operator=(A&);//声明对象赋值重载函数 A&operator=(char*);//声明字符串赋值重载函数 private: char *a; }; A::A(char*init)//定义构造函数 { a=new char[strlen(init)+1];//分配存储空间 strcpy(a,init); cout<<"Constructor:"<<a<<endl; } A& A::operator=(A&x)//定义赋值重载函数 { delete[]a;//释放a所指向的存储空间 a=new char[strlen(x.a)+1];//按新的长度重新分配存储空间 strcpy(a,x.a); cout<<"operator=:"<<a<<endl; return *this; A& A::operator=(char*init)//定义赋值重载函数 a=new char[strlen(init)+1];//按新的长度重新分配存储空间 void main(){ A x("string"),y("str");//调用A(char*)二次 y=x;//调用operator=(A&) x="The string";//调用operator=(char*) 8.2.3 赋值重载函数 在一个类中,若存在指针成员指向动态分配的存储空间的情况,则进行类对象赋值时,同样是把一个对象中指针成员的值赋给另一个对象的相应指针成员中,使它们共同指向同一个动态存储空间。当一个对象中指针成员所指向的存储空间被释放后,致使另一个对象中相应的指针成员指向一个无效的存储空间,为避免这种现象发生,同样可以定义一个赋值操作符重载函数。 例:赋值重载函数举例。

8.2 构造函数 #include<iostream.h> class Time { private: int h,m,s; public: Time(int,int,int); void DisplayTime( ) { cout<<h<<":"<<m<<":"<<s<<endl;} }; Time::Time(int initH,int initM,int initS):h(initH),m(initM),s(initS){ } void main( ) Time t(9,25,45); t.DisplayTime(); } 8.2.4 构造函数中的初始化表 在构造函数中给数据成员赋值时,可以采用两种格式,一种是在函数体中使用赋值语句把表达式的值赋给成员变量,第二种是在形参表后和函数体之前使用初始化表(又称初值表)赋值,并且初始化表同形参表之间必须用冒号分开,初始化表中用逗号分开的每一项用于给一个成员变量赋值,每一项的格式为“成员变量名(初值表达式)”。 例:在构造函数中采用初始化表举例。

8.3 析构函数 析构函数的名字与类名相同,不过应在函数名前加上波折号(~),以示同构造函数的区别。 #include<iostream.h> #include<string.h> class AB { private: int a; char *b; public: AB(int,char*); ~AB();//声明析构函数 }; AB::AB(int aa,char*bb) { a=aa; b=new char[strlen(bb)+1]; strcpy(b,bb); cout<<"Constructor:"<<a<<","<<b<<endl; } AB::~AB( )//定义析构函数 cout<<"Destructor:"<<a<<","<<b<<endl; delete b; void main() AB x(10,"ABC"), *p=new AB(1,"DEFG"); delete p;//调用析构函数撤销对象*p } //调用析构函数撤销对象x 8.3 析构函数 析构函数的名字与类名相同,不过应在函数名前加上波折号(~),以示同构造函数的区别。 析构函数不允许带任何参数(所以析构函数不可能重载),并且也不允许带有返回类型。 析构函数可以同其他成员函数一样由对象调用,但通常析构函数是在对象撤消时由系统自动调用的,并且调用执行后才真正撤消对象。 当用户没有给一个类定义析构函数时,系统隐含给这个类定义一个析构函数,该函数的函数体为空。 由于析构函数是在对象撤消时被自动调用的,所以通常利用析构函数删除对象中由指针成员所指向的动态分配的存储空间,当类中不使用动态存储空间时,则通常不需要定义析构函数。 例:构造函数、析构函数举例。

//使用共用函数实现私有成员的访问 #include<iostream.h> class Complex{ private: double real,imag; public: Complex(double r,double i){real=r; imag=i;}//定义构造函数 double getreal(){return real;}//定义共用函数 double getimag(){return imag;} //定义共用函数 }; void add(Complex &x,Complex &y)//定义普通函数 { double r1,r2,i1,i2; r1=x.getreal(); r2=y.getreal();//获取私有成员信息 i1=x.getimag(); i2=y.getimag(); //获取私有成员信息 double real=r1+r2;cout<<real<<"+"; double imag=i1+i2;cout<<imag<<"i"<<endl; } void main() { Complex z1(5,2.5),z2(-3,0.8); add(z1,z2); 运行结果: 2+3.3i 8.4 友元函数和友元类 在一个类中,类对象的私有成员只能由该类的成员函数访问,外部定义的普通函数和其他类中定义的成员函数都不得访问,这些外部函数只能通过该类提供的公用成员函数访问类对象的私有成员。这将带来很低的访问效率。

//使用友元函数实现复数的加法 #include<iostream.h> class Complex{ private: double real,imag; public: Complex(double r,double i){real=r; imag=i;}//定义构造函数 friend void add(Complex &x,Complex &y);//声明友元函数 }; void add(Complex &x,Complex &y)//定义普通函数 { double real=x.real+y.real;cout<<real<<"+"; double imag=x.imag+y.imag;cout<<imag<<"i"<<endl; } void main() Complex z1(5,2.5),z2(-3,0.8); add(z1,z2); 运行结果: 2+3.3i 8.4 友元函数和友元类 C++允许在一个类中把外部的有关函数或类声明为它的友元函数或友元类,被声明为一个类的友元函数或友元类具有直接访问该类的私有成员的特权。 声明友元函数或友元类的语句以关键字friend开始,后跟一个函数或类的声明。此语句可以放在类中的任何位置,与它前面使用的任一访问权限关键字无关。 例:使用友元函数实现复数的加法。

8.4 友元函数和友元类 例:使用友元类对数组逆置。 例1:友元函数(P251) 例2:友元类(P253) 例3:友元类(P255) //使用友元类对数组逆置 #include<iostream.h> const int n=5; class MyClass;//类MyClass的不完整定义 class YourClass//定义类YourClass { private: int a[n]; friend class MyClass;//声明友元类 public: YourClass(const int&);//声明构造函数 }; YourClass::YourClass(const int&size)//定义构造函数 for(int i=0;i<size;i++) a[i]=i+1; } class MyClass//定义类MyClass void Convert(YourClass&s)//定义实现逆置的成员函数 for(int i=0;i<n/2;i++) { int swap=s.a[i]; s.a[i]=s.a[n-i-1]; s.a[n-i-1]=swap; } void print(YourClass&s)//定义输出数组的成员函数 for(int i=0;i<n;i++) cout<<s.a[i]<<" "; cout<<endl; }; void main( ) YourClass YourObj(n); MyClass MyObj; MyObj.print(YourObj);//输出数组 MyObj.Convert(YourObj);//数组逆置 8.4 友元函数和友元类 例:使用友元类对数组逆置。 例1:友元函数(P251) 例2:友元类(P253) 例3:友元类(P255)

8.4 友元函数和友元类 封装--把类当中的细节隐含起来 友元函数、友元类从某种程度上破坏了数据的封装性,应当有限制地使用。 8.4 友元函数和友元类 封装--把类当中的细节隐含起来 电视机是一个封装好的机器,包含电源、扫描系统、升压系统、电子管等许多环节,而这些内容全部封装在其内部,用户无须关心 电视机提供了一些简单而有效的控制方法,如按键和遥控,用户只需要学会使用这些接口就行了 一个封装好的类是不希望用户去访问其私有成员的,只希望用户访问其共用成员,以保证其纯洁性 友元函数、友元类从某种程度上破坏了数据的封装性,应当有限制地使用。