《C++面向对象程序设计》教案_第1页
《C++面向对象程序设计》教案_第2页
《C++面向对象程序设计》教案_第3页
《C++面向对象程序设计》教案_第4页
《C++面向对象程序设计》教案_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

1、第3章 类和对象3.2 构造函数与析构函数例:点类 Pointclass Point private: int x,y; public: Point() ; Point(int xx, int yy) x=xx; y=yy; Point(Point &p) x=p.x; y=p.y; int GetX() const return x; int GetY() const return y; void SetXY(int xx, int yy) x=xx; y=yy; void Show(); ; void Point:Show() cout<<"X: "

2、<<x<<", Y: "<<y<<endl; 例:人类 Personclass Person protected: char *name; int age; char sex; public: Person(char *n, int a, char s); Person() name = 0; age = 0; sex = ' ' Person( Person &p ); Person() delete name; void SetName(char *n); void SetAge(int a) ag

3、e = a; void SetSex(int s) sex = s; char *GetName() const return name; int GetAge() const return age; char GetSex() const return sex; void Show(); #include "person.h"#include <iostream>using namespace std;Person:Person(char *n, int a, char s) name = new charstrlen(n)+1; strcpy(name,n)

4、; age = a; sex = s;Person:Person(Person &p) name = new charstrlen()+1; strcpy(name,); age = p.age; sex = p.sex; void Person:SetName(char *n) delete name; name = new charstrlen(n)+1; strcpy(name,n);void Person:Show() cout<<"Name: "<<name<<", Age: "

5、;<<age<<", Sex: "<<sex<<endl;3.3 对象数组与对象指针 1、对象数组 所谓对象数组是指每一数组元素都是对象的数组。2、对象指针声明对象指针的一般语法形式为:类名* 对象指针名。当用指向对象的指针来访问对象成员时,要用“->”操作符。 3、this指针C+为成员函数提供了一个名字为this的指针,这个指针称为自引用指针。每当通过一个对象调用一个成员函数时,系统就自动把这个this指针指向该对象。因此使用的数据成员就是该对象的数据成员。3.4 向函数传递对象1、使用对象作为函数参数2、使用对象指

6、针作为函数参数3、使用对象引用作为函数参数3.5 静态成员1、静态数据成员 在一个类中,若将一个数据成员说明为static,这种成员称为静态数据成员。 与一般的数据成员不同,无论建立多少个类的对象,都只有一个静态数据的拷贝。从而实现了同一个类的不同对象之间的数据共享。 定义静态数据成员的格式如下: static 数据类型 数据成员名;静态数据成员在该类定义之外被初始化。访问静态数据成员可以通过对象或指针来访问,也可以通过类名:来访问。2、静态成员函数 定义静态成员函数的格式如下:static 返回类型 静态成员函数名(参数表); 与静态数据成员类似,调用公有静态成员函数的一般格式有如下几种:

7、类名:静态成员函数名(实参表) 对象. 静态成员函数名(实参表) 对象指针->静态成员函数名(实参表)例:点类 Point(演示静态成员)class Point private: int x,y; static int count; public: Point(int xx=0, int yy=0) x=xx; y=yy; count+; Point(Point &p) x=p.x; y=p.y; count+; int GetX() const return x; int GetY() const return y; void SetXY(int xx, int yy) x=x

8、x; y=yy; static int GetCount() return count; ; int Point:count=0;int main() Point a(100,200), b; cout<<a.GetCount(); cout<<Point:GetCount();3.6 友元1、友元函数友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访问该类的所有对象的成员,包括私有成员、保护成员和公有成员。2、友元成员一个类的成员函数也可以作为另一个类的友元,这种成员函数不仅可以访问自己所在类对象中的所有成员,还可以访问friend声明语句所在类对象

9、中的所有成员。3、友元类一个类也可以作为另一个类的友元。友元关系是单向的,不具有交换性。若类X是类Y的友元,类Y不一定是类X的友元。友元关系也不具有传递性。若类X是类Y的友元,Y是类Z的友元,类X不一定是类Z的友元。例:点类 Point(演示友元)class Point private: int x,y; static int count; public: Point(int xx=0, int yy=0) x=xx; y=yy; int GetX() const return x; int GetY() const return y; void SetXY(int xx, int yy) x

10、=xx; y=yy; friend double Dist(Point p1, Point p2); friend double Dist(Point p1, Point p2); double x,y; x=p1.x-p2.x; y=p1.y-p2.y; return sqrt(x*x+y*y);int main() Point a(100,200), b(300,400); cout<<"两点间的距离为:"<<Dist(p1,p2)<<endl;3.7 类对象作为成员例:圆类 Circle(包含Point类的写法)class Circ

11、le private: double radius; /半径 Point center; /圆心 public: Circle() Circle(int x, int y, double r): center(x,y) SetRadius(r); Circle(Point p, double r): center(p) SetRadius(r); double GetRadius() const return radius; void SetRadius(double r) radius = (r>=0 ? r : 0); void SetValue(int x, int y, doub

12、le r) center.SetXY(x,y); SetRadius(r); double Area(); void Show(); const double PI=3.14159; inline double Circle:Area() return PI * radius * radius; void Circle:Show() cout<<"圆心为: "center.Show();cout<<"半径为: "<<radius;3.8 常类型1、const引用 const引用的说明形式如下: const 类型说明符&

13、amp; 引用名2、const对象const对象的说明形式如下: const 类名 对象名(参数表);如:const Data Mybirthday(1980,1,1);const对象的数据成员值不能被改变,const对象必须进行初始化。通过const对象只能调用它的const成员函数,而不能调用普通成员函数。3、const数据成员const数据成员只能通过构造函数的初始化列表来获得初始值。4、const成员函数const成员函数的说明格式如下: 类型说明符 函数名(参数表)const;如:int GetYear() const return year; const成员函数不能更新对象的数据成

14、员,也不能调用对象的普通成员函数。const是函数类型的一个组成部分,因此在函数的实现部分也要带关键字const。5、引用类型的数据成员引用类型的数据成员也只能通过构造函数的初始化列表来进行初始化。例class Test private: int a; const int b;/不能写成const int b=10,因类的定义还没分配空间 int &c; /不能写成const int &c=a,因变量a还没分配空间 public: Test(int i,int j,int &k):b(j),c(k) a=i; Test():b(10),c(a) a=20; 第4章 派生

15、类与继承4.2 派生类的构造函数与析构函数例:圆类 Circle(继承Point类的写法)class Circle: public Point private: double radius; /半径 public: Circle() Circle(int x, int y, double r): Point(x,y) SetRadius(r); Circle(Point p, double r): Point(p) SetRadius(r); double GetRadius() const return radius; void SetRadius(double r) radius = (r

16、>=0 ? r : 0); void SetValue(int x, int y, double r) SetXY(x,y); SetRadius(r); double Area(); void Show(); const double PI=3.14159; inline double Circle:Area() return PI * radius * radius; void Circle:Show() cout<<"圆心为: " Point:Show();cout<<"半径为: "<<radius;关于基

17、类和派生类的几点说明1、派生类继承了它的所有基类中除构造函数和析构函数之外的所有成员。2、在派生类中成员按访问属性划分为四种:不可访问的成员、私有成员、保护成员、公有成员。3、对从基类继承下来的成员初始化工作是通过调用基类的构造函数来完成的,调用方法是在派生类的构造函数中用初始化列表。4、如果在派生类的构造函数省略了基类的初始化列表,则将调用基类的缺省构造函数。5、如果基类定义了带有参数的构造函数时,派生类就应当定义构造函数,以便显式地调用基类的构造函数。6、如果派生类定义了与基类同名的新数据成员或成员函数,则此派生类的成员就覆盖了基类的同名成员,直接使用成员名只能访问到派生类的成员。7、在同

18、名覆盖的情况下,可以使用基类名+作用域分辨符来访问基类的同名成员。8、如果派生类和基类的某个成员函数重名,但参数表不同,仍然属于覆盖,不属于重载。9、对派生类的对象,构造函数的执行过程是:先调用基类的构造函数(按它们被继承时声明的顺序),再调用内嵌对象成员的构造函数(按内嵌对象声明的顺序),最后执行自己的构造函数体中的内容。10、析构函数的调用次序正好和构造函数的调用次序相反。例:学生类 Student/student.h#include "person.h"class Student: public Person protected: char *Department;

19、int Number; public: Student() Department = 0; Number = 0; Student(char *, int, char, char *, int); Student(Student &stu); Student() delete Department; void SetDep(char*); void SetNum(int num) Number = num; char *GetDep() const return Department; int GetNum() const return Number; void Show(); ; /

20、student.cpp#include "student.h"#include <iostream>using namespace std;Student:Student(char *name,int age,char sex,char *dep,int num) : Person(name, age, sex) Department = new charstrlen(dep)+1; strcpy(Department, dep); Number = num;Student:Student(Student &stu): Person(stu) Depar

21、tment = new charstrlen(stu.Department)+1; strcpy(Department, stu.Department); Number = stu.Number; void Student:SetDep(char *dep) delete Department; Department = new charstrlen(dep)+1; strcpy(Department, dep);void Student:Show() Person:Show(); cout<<"Department: " <<Department&

22、lt;<", Number: "<<Number<<endl;4.4 多重继承例1:X和Y是基类,Z从X和Y派生class X public: int b; X(int k) b=k; ;class Y public: int c; Y(int k) c=k; ;class Z: public X, public Y public: int d; Z(int i,int j,int k):X(i),Y(j) d=k; 例2:X和Y都从W派生而来class W public: int a; W(int k) d=k; ;class X: publ

23、ic W public: int b; X(int i, int k): W(i) b=k; ;class Y: public W public: int c; Y(int i, int k): W(i) c=k; ;class Z: public X, public Y public: int d; Z(int i, int j, int k, int l): X(i,j),Y(i,k) d=l; int main() Z t(10,20,30,40); cout<<t.X:a<<t.Y:a<<t.b<<t.c<<t.d<&l

24、t;endl;例3:将W做为X和Y的虚基类class W public: int a; W(int k) a=k; ;class X: virtual public W public: int b; X(int i, int k): W(i) b=k; ;class Y: virtual public W public: int c; Y(int i, int k): W(i) c=k; ;class Z: public X, public Y public: int d; Z(int i, int j, int k, int l): W(i),X(i,j),Y(i,k) d=l; int m

25、ain() Z t(10,20,30,40); cout<<t.a<<t.b<<t.c<<t.d<<endl;在使用虚基类机制时应该注意以下几点:(1) 如果在虚基类中定义有带形参的构造函数,并且没有定义缺省形式的构造函数,则整个继承结构中,所有直接或间接的派生类都必须在构造函数的成员初始化表中列出对虚基类构造函数的调用,以初始化在虚基类中定义的数据成员。(2) 建立一个对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。该派生类的其他基类对虚基类构造函数的调用都

26、自动被忽略。(3) 若同一层次中同时包含虚基类和非虚基类,应先调用虚基类的构造函数,再调用非虚基类的构造函数,最后调用派生类构造函数;(4) 对于多个虚基类,构造函数的执行顺序仍然是先左后右,自上而下;(5) 对于非虚基类,构造函数的执行顺序仍是先左后右,自上而下;(6) 若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。4.5 赋值兼容规则所谓赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。附:线性表顺序表class SeqList private: int *data; int size; int MaxSize; publi

27、c: SeqList(int sz=100); SeqList() delete data; int Length() const return size; bool IsEmpty() const return size=0; void Insert(const int &x, int k); void Delete(int k); int GetData(int k) const; int Find(const int &x) const; void Show() const; ; SeqList:SeqList(int sz) MaxSize=sz; data=new i

28、ntMaxSize; size=0; void SeqList:Insert(const int &x, int k) if( k<1 | k>size+1 ) cerr<<"越界出错" exit(1); if(size=MaxSize) cerr<<"顺序表已满" exit(1); for(int i=size-1; i>=k-1; i-) datai+1=datai; datak-1=x; size+; void SeqList:Delete(int k) if(size=0) cerr<<

29、;"顺序表空" exit(1); if( k<1 | k>size ) cerr<<"越界出错" exit(1); for(int i=k; i<size; i+) datai-1=datai; size-; int SeqList:GetData(int k) const if( k<1 | k>size ) cerr<<"越界出错" exit(1); return datak-1; int SeqList:Find(const int &x) const for(int

30、 i=0; i<size; i+) if(datai=x) return i+1; return 0; void SeqList:Show() const for(int i=0; i<size; i+) out<<datai<<" " 第5章 多态性5.3 运算符重载例:复数类Complex/mycomplex.h #include <iostream>using namespace std;class Complex private: double re, im; public: Complex(double r=0, d

31、ouble i=0) re=r; im=i; double real() return re; double imag() return im; Complex operator+() return *this; Complex operator-() return Complex(-re, -im); Complex &operator+=( Complex & ); Complex &operator-=( Complex & ); Complex &operator*=( Complex & ); Complex &operator

32、/=( Complex & ); friend Complex operator+( Complex &, Complex & ); friend Complex operator-( Complex &, Complex & ); friend Complex operator*( Complex &, Complex & ); friend Complex operator/( Complex &, Complex & ); friend bool operator=( Complex &, Complex &

33、amp; ); friend bool operator!=( Complex &, Complex & ); friend ostream &operator<<( ostream &, Complex & ); friend istream &operator>>( istream &, Complex & ); operator double() return re; ;/mycomplex.cpp#include"mycomplex.h"#include <iostream

34、>using namespace std;Complex &Complex:operator+=( Complex &c ) re += c.re; im += c.im; return *this;Complex &Complex:operator-=( Complex &c ) re -= c.re; im -= c.im; return *this;Complex &Complex:operator*=( Complex &c ) double t = re * c.re - im * c.im; im = re * c.im + i

35、m * c.re; re = t; return *this;Complex &Complex:operator/=( Complex &c ) double m = c.re * c.re + c.im * c.im; double t = (re * c.re + im * c.im) / m; im = (im * c.re - re * c.im) / m; re = t; return *this;Complex operator+( Complex &a, Complex &b ) return Complex( a.re + b.re, a.im

36、+ b.im );Complex operator-( Complex &a, Complex &b ) return Complex( a.re - b.re, a.im - b.im );Complex operator*( Complex &a, Complex &b ) return Complex( a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re );Complex operator/( Complex &a, Complex &b ) double m = b.re * b.r

37、e + b.im * b.im; return Complex( (a.re * b.re + a.im * b.im) / m, (a.im * b.re - a.re * b.im) / m );bool operator=( Complex &a, Complex &b ) return a.re = b.re && a.im = b.im;bool operator!=( Complex &a, Complex &b ) return a.re != b.re | a.im != b.im;ostream &operator<

38、;<( ostream &os, Complex &c ) os << c.re << '+' << c.im << 'i' return os;istream &operator>>( istream &is, Complex &c ) is >> c.re >> c.im ; return is;例:分数类 Fraction #include <iostream>using namespace std;class Fr

39、action private: int num, den; void reduce(); public: Fraction(int n=0, int d=1); Fraction operator+() return *this; Fraction operator-() return Fraction(-num, den); Fraction &operator+=(Fraction &); Fraction &operator-=(Fraction &); Fraction &operator*=(Fraction &); Fraction

40、&operator/=(Fraction &); Fraction &operator+(); Fraction operator+(int); operator double(); friend Fraction operator+(Fraction &, Fraction &); friend Fraction operator-(Fraction &, Fraction &); friend Fraction operator*(Fraction &, Fraction &); friend Fraction ope

41、rator/(Fraction &, Fraction &); friend bool operator=(Fraction &, Fraction &); friend bool operator!=(Fraction &, Fraction &); friend bool operator<(Fraction &, Fraction &); friend bool operator<=(Fraction &, Fraction &); friend bool operator>(Fractio

42、n &, Fraction &); friend bool operator>=(Fraction &, Fraction &); friend ostream &operator<<(ostream &, Fraction &); friend istream &operator>>(istream &, Fraction &);#include "fraction.h"#include <iostream>using namespace std;Fr

43、action:Fraction(int n, int d) num = n; den = d; if(den=0) den = 1; reduce();Fraction &Fraction:operator+=(Fraction &f) num = num * f.den + den * f.num; den = den * f.den; reduce(); return *this;Fraction &Fraction:operator-=(Fraction &f) num = num * f.den - den * f.num; den = den * f.

44、den; reduce(); return *this;Fraction &Fraction:operator*=(Fraction &f) num = num * f.num; den = den * f.den; reduce(); return *this;Fraction &Fraction:operator/=(Fraction &f) num = num * f.den; den = den * f.num; reduce(); return *this;Fraction &Fraction:operator+() num += den; r

45、eturn *this;Fraction Fraction:operator+(int) Fraction temp = *this; num += den; return temp;Fraction:operator double() return static_cast<double>(num) / den;Fraction operator+(Fraction &x, Fraction &y) return Fraction(x.num * y.den + x.den * y.num, x.den * y.den);Fraction operator-(Fra

46、ction &x, Fraction &y) return Fraction(x.num * y.den - x.den * y.num, x.den * y.den);Fraction operator*(Fraction &x, Fraction &y) return Fraction(x.num * y.num, x.den * y.den);Fraction operator/(Fraction &x, Fraction &y) return Fraction(x.num * y.den, x.den * y.num);bool oper

47、ator=(Fraction &x, Fraction &y) return( x.num * y.den = x.den * y.num);bool operator!=(Fraction &x, Fraction &y) return !(x = y);bool operator<(Fraction &x, Fraction &y) return( x.num * y.den < x.den * y.num);bool operator<=(Fraction &x, Fraction &y) return !

48、(y > x);bool operator>(Fraction &x, Fraction &y) return (y < x);bool operator>=(Fraction &x, Fraction &y) return !(x < y);ostream &operator<<(ostream &os, Fraction &f) return os << f.num << '/' << f.den;istream &operator&

49、gt;>(istream &is, Fraction &f) char ch; is >> f.num >> ch >> f.den; return is;int gcd(int m, int n) int k; while( n != 0 ) k = m % n; m = n; n = k; return m; void Fraction:reduce() if(den < 0) num = -num; den = -den; if(den = 1) return; int sgn = num<0 ? -1 : 1; int g = gcd(sgn*num, den); num /= g; den /= g; 例:在人类Person中增加重载赋值运算符在Person.h中增加一个说明: Person & operator=(P

温馨提示

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

评论

0/150

提交评论