书签 分享 收藏 举报 版权申诉 / 49
上传文档赚钱

类型物件导向程式语言讲义课件.ppt

  • 上传人(卖家):晟晟文业
  • 文档编号:3727525
  • 上传时间:2022-10-07
  • 格式:PPT
  • 页数:49
  • 大小:148.69KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《物件导向程式语言讲义课件.ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    物件 导向 程式 语言 讲义 课件
    资源描述:

    1、Derived Class 前言 衍生類別的定義 單一繼承 public,protected,和 privated 基底類別 virtual 成員函式 RTTI(Run-time Type Information)前言前言C+提供類別繼承的機制來擴充或更改現有類別的功能。我們可以利用此機制來達到以下兩個目的:程式碼的再利用(code reuse)物件導向的設計(object-oriented design)假定 B 是一個類別。我們可以用底下的格式來定義一個 B 的衍生類別 D:class D :public B/members of D;我們稱:D 繼承 B、B 是 D 的 base cla

    2、ss(基底類別)或 superclass(父類別)、以及 D 是 B 的 derived class(衍生類別)或 subclass(子類別)。衍生類別的定義衍生類別的定義class Bclass D類別繼承的圖示類別繼承通常是用來表達 kind-of 關係(或稱 is-a 關係):衍生類別是基底類別的一種。譬如:Manager(經理)也是 Employee(員工),所以我們先規劃好 Employee 類別,然後把 Manager 定義成 Employee 的一個衍生類別:class Employee/other membersprivate:string first_name,family_

    3、name;char middle_initial;Date hiring_date;short department;class Manager:public Employee/other membersprivate:set group;short level;Manager 的資料成員:string first_name,family_name;char middle_initial;Date hiring_date;short department;set group;short level;衍生類別除了本身的資料成員以外,也具有基底類別的資料成員。譬如:Employee 的資料成員:s

    4、tring first_name,family_name;char middle_initial;Date hiring_date;short department;由於衍生類別是基底類別的子類別,因此衍生類別的物件可視為基底類別的物件;基底類別型態的指標也可用於衍生類別的物件,而不須要經過型態轉換。但反過來就不成立了。譬如:void foo(Manager mm,Employee ee)Employee*pe=&mm;/okManager*pm=ⅇ/errorpe-level=2;/error:Employee doesnt have/data member:levelpm=stati

    5、c_cast(pe);/ok:explicit type castingpm-level=2;/ok:since pe points to a/Manager object衍生類別及其朋友(friends)可以直接使用基底類別的 public 或 protected 成員,但是不能使用基底類別的 private 成員。譬如:class B public:void f();protected:void g();int _x;private:void h();int _y;class D:public B friend void k(D);void a()f();/okvoid b()g();/o

    6、kvoid c()_x=0;/ok void d()h();/errorvoid e()_y=0;/error;void k(D obj)obj.g();/okobj.f();/okobj._x=0;/okobj._y=0;/error存取控制存取控制 本身與其朋友 衍生類別與其朋友外界publicprotectedprivatexxx我們用下表來總結類別成員的存取控制:如果基底類別的成員函式不符合所需的話,我們可以在衍生類別中重新改寫(override)。譬如:class Employee public:void print();/other members;void Employee:pr

    7、int()cout first_name middle_initial family_name;class Manager:public Employee public:void print();/other members;void Manager:print()Employee:print();cout level;這項改寫的機制讓 code reuse 可以很容易地達成。衍生類別的建構函式必須呼叫基底類別的建構函式(如果它存在的話),而且前者的參數必須包含後者的參數。譬如:class Employee public:Employee(const string&n,int d):famil

    8、y_name(n),department(d)/other members;class Manager:public Employee public:Manager(const string&n,int d,int lvl):Employee(n,d),level(lvl)/other members;衍生類別的物件建構順序如下:1.執行基底類別的建構函式。2.執行衍生類別資料成員的建構函式。3.執行衍生類別的建構函式。衍生類別的物件解構順序則恰恰相反,即:1.執行衍生類別的解構函式。2.執行衍生類別資料成員的解構函式。3.執行基底類別的解構函式。資料成員和基底類別是按照宣告的順序來建構,解構

    9、則按照相反的順序。拷貝衍生類別物件至基底類別物件時,只拷貝基底類別的資料成員。class Employee Employee(const Employee&);Employee&operator=(const Employee&);/;void f(const Manager&m)Employee e=m;/construct e from Employee part of me=m;/assign Employee part of m to e範例class CPoint2D public:CPoint2D(int x=0,int y=0):_x(x),_y(y)int x()return

    10、_x;int y()return _y;void setX(int x)_x=x;void setY(int y)_y=y;void set(int x,int y)_x=x;_y=y;bool isZero()return _x=0&_y=0;double distance()return sqrt(_x*_x+_y*_y);protected:int _x,_y;我們利用 CPoint2D 類別來定義 CPoint3D 類別。首先我們把 CPoint2D 的 private 成員改成 protected 成員,讓 CPoint3D 可以使用它們。class CPoint3D:public

    11、CPoint2D public:CPoint3D(int x=0,int y=0,int _z=0):CPoint2D(x,y),_z(z)int z()return _z;void setZ(int z)_z=x;void set(int x,int y,int z)set(x,y);setZ(z);bool isZero()return _x=0&_y=0&_z=0;double distance()return sqrt(_x*_x+_y*_y+_z*_z);private:int _z;CPoint3D 改寫(override)CPoint2D 的 isZero()和 distance

    12、()函式。#include using namespace std;#include“CPoint3D.h”ostream&operator(ostream&os,CPoint3D p)os (p.x()“,“p.y()“,“p.z();return os;我們可以為 CPoint3D 類別定義輸出運算子 如下:測試程式#include“CPoint3D.h”int main()CPoint3D p(1,2,3);cout p endl;CPoint2D q(5,6);q=p;cout q endl;p=q;/error輸出結果(1,2,3)(1,2)範例typedef unsigned sh

    13、ort big5char;class big5string:public string public:bool is_big5char(int idx);big5char next_char(int idx);int big5_length();private:bool in(char c,int min,int max)return min=c&c=0&idx length();char*cp=c_str();if(cpidx 128|idx=length()-1)return false;if(is_big5hiByte(cpidx)&is_big5loByte(cpidx+1)retur

    14、n true;elsereturn false;big5char big5string:next_char(int idx)char*cp=c_str();return is_big5char(idx)?cpidx*256+cpidx:cpidx;int big5string:big5_length()int len=0,k=0;while(k length()k=is_big5char(k)?k+2:k+1;len+;return len;測試程式#include#include#include“big5string.h”int main()string s1(“Hi,“);big5stri

    15、ng s2;s2=s1+“好久不見”;cout s2 endl;cout “#of characters is:“s2.big5_length()print();其實不然。原因是:e 是 Employee 型態的指標,所以不論傳進來的引數型態是 Employee、Manager、或 Director,e-print()永遠是呼叫 Employee 的成員函式 print()。你可以在 Employee 類別中,加入一個儲存員工類型的資料成員來解決前述的問題。譬如:class Employee public:enum emp_type EMPLOYEE,MANAGER,DIRECTOR;void

    16、 print();emp_type type()return _type;/private:emp_type _type;並在三個類別的建構函式中,加入資料成員 type 的設定。經過這些加工之後,你就可以寫出下一頁的列印函式。void print_emp(Employee*e)switch(e-type()case Employee:EMPLOYEE:e-print();break;case Employee:MANAGER:static_cast(e)-print();/Managers print()break;case Employee:DIRECTOR:static_cast(e)-

    17、print();/Directors print()break;上述的解決方案有下面兩個缺點:就如同 print_emp()函式所示,程式設計師必須判斷物件的類別,然後採取適當的型態轉換。這種作法不僅增加程式撰寫的負擔,也容易造成錯誤。print_emp()函式只能列印 Employee、Manager、和 Director 三種類別的物件。如果其他人用繼承的方式定義另一種員工的類別,如 Secretary,則已經寫死的 print_emp()函式將無法用來列印這個新類別的物件。class Secretary:public Employee public:void print();/;為了解決

    18、上述的問題,C+提供一種稱為 virtual 函式的特別成員函式。你只要在成員函式的宣告之前加上關鍵字 virtual,就可以把它變成 virtual 函式,即virtual return_type func_name(parameter list)當類別含有 virtual 成員函式時,C+編譯器會為它產生一個 virtual function table,其中包含此類別所有 virtual 成員函式的位址。此外,屬於此類別的物件,除了儲存資料成員外,會另外儲存一個指向此 virtual function table 的指標。宣告宣告 virtual 函式函式舉例來說,假定類別 X 的宣告如

    19、下:class X public:virtual void vf1();virtual void vf2();void f();private:int _x,_y;X a,b;則 X 類別的物件結構將如右圖所示。_x_y_ _vptr_ _XX:vf1()X:vf1()virtual tablefor class X_x_y_ _vptr_ _Xab衍生類別的 virtual 函式會覆蓋(override)基底類別的同名同參數列的 virtual 函式。class Base virtual void foo(int);/other members;class Derived:public Ba

    20、sevirtual void foo(int);/other members;override若我們把前述 Employee 類別和它衍生類別中的 print()成員函式都改成 virtual(如左圖所示),則函式 print_emp()就變得簡單多了,而且也克服前述的一些缺點。class Employee public:virtual void print();/;class Manager:public Employee public:virtual void print();/;class Director:Manager public:virtual void print();/;利用

    21、 virtual 函式的 print_emp()定義如下:void print_emp(Employee*e)e-print();則 e-print()會呼叫傳進來物件所定義的 print()成員函式。譬如:若傳進來 Emploee 型態的物件時,e-print()等同於e-Emploee:print();若是 Manager 型態的物件時,e-print()等同於 e-Manager:print()。型態相同的物件(都是 Employee)卻具有不同的行為(不同的 print()功能),稱之為 polymorphism(多型)。具有 virtual 成員函式的類別稱為多型型態(polymor

    22、phic type)。在 C+中,若要使用多型,你必須:把一些成員函式定義成 virtual。透過物件指標或參照來呼叫這些 virtual 成員函式。若透過物件直接呼叫 virtual 成員函式,因為編譯時會固定呼叫的對像,所以會達不到多型的效果。譬如:Employee e;e.print();/一定呼叫 Employee:print()Pure Virtual Functions如果基底類別的 virtual 成員函式只是用來規定衍生類別應該具備的使用介面(interface),而且基底類別也不用來定義物件的話,我們可以用以下的格式把 virtual 成員函式設定無定義的函式:virtual

    23、 return_type fucn_name(parameter_list)=0這樣的函式稱為 pure virtual function。Abstract Classes本身擁有或繼承但不改變 pure virtual functions 的類別稱為抽象類別(abstract class)。由於 pure virtual functions 是沒有定義的函式,因此抽象類別不可用來定義物件。譬如底下的 Abstract_Base 和Abstract_Derived 是抽象類別,而 Concrete_Derived 就不再是了:class Abstract_Base public:virtual

    24、 void foo()=0;class Abstract_Derived:public Abstract_Base /*/class Concrete_Derived:public Abstract_Base public:virtual void foo();/no longer pure抽象類別通常製訂介面(interface)用來規範衍生類別的基本功能。譬如:class Shape public:/所有 Shape 類別物件都必須提供下列的功能virtual void rotate(int)=0;virtual void draw()=0;virtual void is_closed(i

    25、nt)=0;class Circle:public Shape public:virtual void rotate(int)/*function definition*/virtual void draw()/*function definition*/virtual void is_closed(int)/*function definition*/other membersRTTI(Run-time Type Information)C+的 RTTI 的機制提供下面兩個功能:dynamic_cast typeiddynamic_castdynamic_cast(p)=p 0如果指標 p

    26、所指的物件型態是 T 或其基底類別是 T。所有其他情形void f(Derived*p)Base*q0=p;/okBase*q1=dynamic_cast(p);/okOther*q2=p;/compile errorOther*q3=dynamic_cast(p);/ok:q3 is 0假定 Base 是 Derived 的基底類別,Other 是與它們無任何繼續關係的類別typeidtypeid 運算子可用來取得物件的型態資訊:typeid(obj);/傳回物件 obj 的型態資訊typeid(*objptr);/傳回物件指標 objptr 所指物件的型態資訊我們可以從型態資訊中取得型態的名稱,如:typeid(obj).name();/物件 obj 所屬類別的名稱也可以比較兩個物件的型態是否相同,如typeid(obj1)=typeid(obj2)/true 若兩物件的類別相同typeid(obj1)!=typeid(obj2)/true 若兩物件的類別不相同

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:物件导向程式语言讲义课件.ppt
    链接地址:https://www.163wenku.com/p-3727525.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库