1 / 38

第三章 类和对象

第三章 类和对象. 要求: 掌握类的设计方法 掌握对象的创建方法. 类-类的定义. 一般形式. 外部程序不可见。只能由该类对象的成员函数、以及被声明为友元的函数或声明为友元的类的对象的成员函数访问. class 类名 { private : 私用数据成员和成员函数 protected : 保护数据成员和成员函数 public : 公用数据成员和成员函数 } ;. 允许该类的派生类访问. 外部程序可见。允许程序中其他函数或其他类的对象的成员函数访问。. 例 3 - 1 复数类设计. 私有数据成员: 实部、虚部;

alaqua
Download Presentation

第三章 类和对象

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第三章 类和对象 要求: 掌握类的设计方法 掌握对象的创建方法

  2. 类-类的定义 • 一般形式 • 外部程序不可见。只能由该类对象的成员函数、以及被声明为友元的函数或声明为友元的类的对象的成员函数访问 class 类名 { private: 私用数据成员和成员函数 protected : 保护数据成员和成员函数 public: 公用数据成员和成员函数 }; • 允许该类的派生类访问 • 外部程序可见。允许程序中其他函数或其他类的对象的成员函数访问。

  3. 例3-1 复数类设计 • 私有数据成员: 实部、虚部; • 公有成员函数:加、减、乘、除运算、输出; Complex Add(Complex x) { Complex z; z.real=real+x.real; z.imag=imag+x.imag; Return z; } Complex Sub(Complex x) { Complex z; z.real=real-x.real; z.imag=imag-x.imag; Return z; } #include<iostream.h> Class Complex { Private: float real; float imag; Public: Complex(float x=0,float y=0) { real=x; imag=y; } ~complex() {}

  4. 例3-1 复数类设计 { z.real=(real*x.real+imag*x.imag)/c; z.imag=(x.real*imag-real*x.imag)/c; return z; } } Void show() { cout<<“real is”<<real; cout<<“imag is”<<imag<<endl; } }; Complex Multi(Complex x) { Complex z; z.real=real*x.rea-imag*x.imagl; z.imag=real*x.image+x.real*imag; return z; } Complex Divide(Complex x) { Complex z; float c=x.real*x.real+x.imag*x.imag; if (c==0) { cout<<“分母为0错!”; exit(0); } else

  5. 类-成员变量 • 数据类型 • 任何C++的基本数据类型和用户自定义数据类型 • C++的基本类类型 • 用户自定义类类型(但不能递规) • 访问权限 • 一般设为私有 • 初始化 • 不在定义时完成,创建对象时由构造函数完成 Class student { Private: student x; };

  6. 类-构造函数和类的实例化 • 构造函数 • 定义 - 特殊的成员函数。创建类的实例时,系统自动调用,完成对象的初始化赋值工作。 • 设计方法 • 构造函数名与类型完全相同,不能有返回值 • 参数用来传递定义对象时的初始值,可以为空。 • 允许有默认值,给出所有参数的默认值,可以定义数组对象 • 访问权限为public • 可以重载 • 参数可以是一个已有初始化数值的对象,这种构造函数称作拷贝构造函数。

  7. 类-构造函数和类的实例化 • 构造函数 • 两种格式 Complex(float x=0, float y=0) { real=x; imag=y; } Complex(float x=0, float y=0): rea(x),imag(y){} • 两种位置 • 类定义体外定义 • 类定义体内定义 Complex::Complex(float x=0,y=0):real(x),imag(y){}

  8. 类-构造函数和类的实例化 • 类的实例化 • 格式 类名 对象名(实参表) 例: Complex x(1,2), y(3,4); Complex x,y; 说明:用默认值初始化对象时,或没有参数时,对象名后边一定不能有括号! • 实例化时,为对象的成员变量分配内存空间 P52, 如图3.1

  9. 例3-2 构造函数重载、拷贝构造函数 //Date.h #include <iostream.h>   class Date { private: int month; int day; int year; public: //构造函数,内联函数方式,带有默认初始值 Date(int m = 1, int d = 1, int y = 2000):month(m), day(d), year(y){} Date(Date &d) //拷贝构造函数 {month = d.month; day = d.day; year = d.year;} ~Date(void) {} void PrintDate(void) const {cout << month << "-" << day << "-" << year << endl;} };

  10. 例3-2 构造函数重载、拷贝构造函数 #include "Date.h" void main(void) //测试主函数 { Date today(8, 23, 2001); //带初始值的对象定义 Date someDay; //使用默认值的对象定义 Date someDay2(today); //使用拷贝构造函数的对象定义 Date someArrayDay[4]; //使用默认值的数组对象定义 today.PrintDate(); //打印初始值日期 someDay.PrintDate(); //打印默认值日期 someDay2.PrintDate(); //打印对象today的日期 someArrayDay[0].PrintDate(); //打印默认值日期 someArrayDay[3].PrintDate(); //打印默认值日期 } 所有参数采用默认值,或构造函数为空,对象后不带括号

  11. 类-成员函数和对象的消息 • 成员函数 • 定义 -为外部程序提供一定服务的公共程序接口 • 访问权限(private, public、protected) • 一般格式 返回类型 类名::成员函数名(形参表) { 函数体; }

  12. 类-成员函数和对象的消息 Class Comlex { …… Complex Add(Complex x) ; …… } • 成员函数重载 • 设计(声明和实现) • 内联函数方式: 声明和实现都在类定义内 • 外联函数方式:声明在类内,实现在类外 Complex Comlplex::Add(Complex x) { Complex z; z.real=real+x.real; z.imag=imag+x.imag; Return z; }

  13. 类-成员函数和对象的消息 • 通过对象调用成员函数 • 格式: 对象名. 成员函数(实参表) 例:void main(void) { Complex x(1,1), y(2,2), z1; z1=x.Sub(y); z1.show(); }

  14. 例3-3 成员函数重载 #include<iostream.h> Class Complex { Private: float real; float imag; Public: Complex(float x=0,float y=0): real(x),imag(x);{} ~complex() {} Complex Add(const Complex x)const; Complex Add(const float x)const; void show(void) const; }; Complex Complex::Add(const Complex x)const { return Complex(real+x.real, image+y.imag); } Complex Complex::Add( const float x) const { return Complex(real+x,imag); } Void Complex::show(void)const { cout<<“real is”<<real; cout<<“imag is”<<image<<endl; } 成员函数只能读取当前对象的成员变量,但不能修改。 该参数在成员函数内不能被修改

  15. 类-成员函数设计原则 • 一般采用成员函数设计成外联函数。 • 当成员函数的某个参数在函数体内不会或不应该被修改时,用const关键字修饰。 • 当成员函数只能读取类中成员变量,但不能修改时,用const修饰该成员函数。 • 成员函数的输出型参数,应设计成引用类型。

  16. 类-析构函数 • 定义 • 特殊的成员函数,每当对象运行到超出作用域时,系统都自动调用析构函数。 • 格式:与类同名,不带参数,无返回值 外联实现: ~ 类名(void) 空析构: ~类名(){} • 一般包含delete语句,也可以是空函数 • 作用 • 释放程序中用new申请的动态内存空间。 • 调用delete运算符时,系统自动定义析构函数,完成一些特殊扫尾工作。

  17. 例3-4 析构函数 #include<iostream.h> #include<stdlib.h> Class Array { Private: double *arr; int size; Public: Array(int sz=0); ~Array(void); }; Array::Array(int sz) { if(sz<=0) { cout<<“参数错“<<endl; exit(0); } size=sz; arr=new double[size]; } Array::~Array(void) { delete[]arr; } Void main(void) { Array a(10); }

  18. 对象-定义 • 对象的创建方法 • 用户定义,系统自动调用构造函数给对象成员变量赋初值。 类名 对象名(参数); 类名 对象名; 类名 对象名[N]; • 需要时调用new操作符建立 Date *p; p=New Date; delete p; • 引用对象的成员 • <对象名>.<成员> • <指向对象的指针>.<成员> p->month

  19. 例3-5 对私有成员变量的设置 #include<iostream.h> #include<complex.h> Void main(void) { Complex x(1,2),y(3,4),z; z=x.Add(y); x.real=10; z.show; } 外部程序定义的对象无权访问类的私有成员变量 调用无参数成员函数,也要带()

  20. 例3-5 对私有成员变量的设置 //complex.h #include<iostream.h> Class Complex { Private: float real; float imag; Public: Complex(float x=0,float y=0): real(x),imag(x);{} ~complex() {} …… Float getReal(void)const; Float setReal(const float x); }; Float Complex:: getReal(void) { return real; } Float Complex::setReal(const float x) { real=x; } Void main(void) { Const Complex x(1,2); Complex y, z; x.setReal(3); y.setReal(3); z=x.Add(y); cout<<“z real part is”<< z.getReal();<<endl; } Const对象只能通过构造函数一次初始化赋值

  21. 例3-6 创建动态对象 #include”complex.h> Void main(void) { Complex z; complex *x=new complex(1,2); complex *y; y=new complex(3,4); z=x->Add(*y); cout<<“z real part is :”<<z.getReal()<<endl; delete x; delete y; }

  22. 对象成员变量 • 整体-部分模式实现 • 定义表示部分概念的类,也称内层类 • 定义表示整体概念的类,也称外层类 • 在整体类中有一个成员变量,它的类型是部分概念类。称该成员变量为子对象 • 整体类构造函数设计 • 显示调用子对象的拷贝构造函数为子对象赋初值 • 显示调用子对象的构造函数为子对象赋初值

  23. 例3-6 整体-部分模式实现 class Line { private: Point a; Point b; public: Line(int X1, int Y1, int X2, intY2): a(X1, Y1),b(X2, Y2){} Line(Point &aa, Point &bb):a(aa),b(bb) {} ~Line(void){} void ShowA(void)const { cout<<“a point is (“<<a.Get() <<“,”<<a.GetY()<<“)”; } }; #include<iostream.h> #include <graphics.h> class Point { private: int x; int y; public: Point(int iniX, int iniY) {x = iniX; y = iniY;} Point(Point &c):x(c.x),y(c.y){} ~Point(void){} int GetX(void)const { return x; }…… };

  24. 例3-6 整体-部分模式实现 #include”……” Void main(void) { Line myLine1(1,1,5,5); myLine1.ShowA(); myLine1.ShowB(); Point a(10,10),b(50,50); Line myLine2(a,b); myLine1.ShowA(); myLine1.ShowB(); }

  25. 例3-7 class Point { private: int x; int y; public: Point(int iniX, int iniY): x(iniX), y(iniY){cout << "类Point构造函数调用" << endl;} Point(Point &a): x(a.x), y(a.y){cout << "类Point拷贝构造函数调用" << endl;} ~Point(void){cout << "类Point析构函数调用" << endl;} }; class Line { private: Point a; Point b;

  26. 例3-7 public: Line(int iniX1, int iniY1, int iniX2, int iniY2): a(iniX1, iniY1), b(iniX2, iniY2) {cout << "类Line构造函数1调用" << endl;} Line(Point &aa, Point &bb): a(aa), b(bb) {cout << "类Line构造函数2调用" << endl;} ~Line(void) {cout << "类Line析构函数调用" << endl;} }; void main(void) { cout << "构造函数调用过程:" << endl; Line myLine(1,1,5,5); Point a(1,1), b(5,5); Line myLine2(a, b); cout << "析构函数调用过程:" << endl; }

  27. 内部类 • 定义 -当一个类只为另一个类服务时,把它定义在另一个类中,并将其称作内部类,封装有内部类的类称作外部类。 • 规则 • 内部类对外部程序不可见,外部程序不能用它来定义对象 • 外部类无法直接访问内部类的私有成员 • 内部类无法直接访问外部类的私有成员

  28. 例3-8 用内部类方式设计线段类。 Public: Line(int X1=0, int Y1=0, int X2=0, int Y2=0): a(X1, Y1), b(X2, Y2){} ~Line(void){} void ShowA(void)const { cout<<“a point is:(“<<a.x<< “,”<<a.y<<“)”<<endl; } …… }; Void main(void) { Point a(10,10),b(50,50); Line myLine(0,10,50,50); myLine.ShowA(); myLineShowB(); } #include<iostream.h> Class Line { class { public: int x; int y; public: Point(int iniX=0, int iniY=0): x(iniX), y(iniY){} ~Point(void){;} }; Private: point a; point b;

  29. static成员 • static 变量 • static变量在编译时分配内存空间,直到整个程序(即主程序)执行完才撤消。 • static变量在编译时进行初始化。如果用户不给初始化值,编译程序自动给出 Main() { int a=2, i; for(i=0;i<3;i++) { printf(“%d”,f(a)); } } f ( int a) { int b=0; static int c=3; b=b+3; c=c+3; Return(a+b+c); }

  30. static成员变量 • 引入原因 • 有些特殊的数据成员为某个类的所有对象所共享,也就是它不是属于具体的对象,而是属于整个类。 • 定义 • 成员变量前加static关键字,成为static成员变量 • 初始化赋值 • 不能用构造函数初始化赋值; • 不能放在主函数中初始化; • 在程序定义该类的任何对象之前,对类中的static数据成员单独初始化; • 文件范围内使用下边语句格式进行初始化: <类名>::<static数据成员名 >= <初始化值>;

  31. Static成员函数 • 引入原因 - 对static数据成员的访问。 • 定义 - 函数定义前加static关键字 - 一般为公有,也可以定义为私有 • 调用 <类名>::<static 成员函数名>(<参数表>)

  32. 例3-9 static成员变量 class Employee { private: char name[30]; float salary; static float allSalary; Public: Employee(char *n, float s) { strcpy(name, n); salary = s; allSalary = allSalary + salary; } ~Employee(void) { allSalary = allSalary – salary; } static float GetAllSalary(void) { return allSalary; } }; Float Employee::allSalary = 0; Void main(void) { Employee e1("张", 100); Employee e2("王", 200); Employee e3("李", 300); float all; all = Employee::GetAllSalary(); cout << "AllSalary = " << all << endl; }

  33. 4.7 自引用对象指针this • 当用户创建对象时,c++系统为该对象建立了一个this指针,各个对象的this指针指向对象的开始地址 • This指针可以用来表示当前对象 • this指针一般在成员函数中使用,通过this指针调用数据成员。例如:在Date类的构造函数中 Date::Date(int month, int day, int year) { this->month = month; this->day = day; this->year = year; }

  34. 例3-8 设计举例-银行贷记卡系统 • 设计要求 • 客户存款、取款和转帐,允许客户取款时透支(即欠款) • 客户余额输出采用类似3元3角1分这样的格式 • 设计一个主程序进行基本情况演示 • 设计分析 • 贷记卡类: • 成员变量:客户帐号、姓名、余额 • 成员函数:存款、取款、转帐、输出 • 余额类

  35. Void Money::Add(const float x) { amount=amount+x; } Void Money::Sub(const float x) { amount=amount-x; } Void Money::Print(void)const { float temp=amount; if(amount>=0) { cout<<“余额:”; } else { cout<<“欠款:”; temp=-temp; } //Account.h #include<string.h> #include<math.h> #include<iostream.h> Class Money { Private: float amount; Public: Money(float a=0):amount(a) {} ~Money() {} void Add(const float x); void Sub(const float x); void Print(void)const; };

  36. ~Account(){} Void Add(const float x); Void Sub(const float x); Void transfer(Account &a, const float x); Void Print(void)const; }; Void Account::Add(const float x) { remains.Add(x); } Void Account::Sub(const float x) { remains.Sub(x); } Void Account::transfer(Account &a, const float x) { remains.Sub(x); a.remains.Add(x); } int yuan=int(temp); cout<<yuan<<“元”; int jiao=int((temp-yuan)*10); cout<<jiao<<“角”; int fen=int(ceil(temp*100- yuan*100.0-jioa*10.0)); cout<<fen<<“分”<<endl; } Class Account { Private: long accountNo; char name[30]; Money remains; Public: Account(long a,char *n,Money r): accountNo(a),remains( r) { strcpy(name,n); }

  37. Void Account::Print(void)const { cout<<“姓名:”<<name<<endl; cout<<“帐号:”<<accountNo<<endl; remains.Print(x); } #include”Account.h” Void main(void) { Accounta1(100000,”张三“,Money(3.31)); Accounta2(100001,”李四”,Money(40.42)); Accounta2(100002,”王五”,Money(40.42)); a1.transfer(a2,100); a2.Add(50); a3.Sub(100); a1.Print(); a2.Print(); a3.Print(); }

  38. 作业 • P88, 3.28,3.29,3.30, 3.32, 3.33

More Related