面向對象程序設計課件_第1頁
面向對象程序設計課件_第2頁
面向對象程序設計課件_第3頁
面向對象程序設計課件_第4頁
面向對象程序設計課件_第5頁
已閱讀5頁,還剩205頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

面向對象程式設計

第一章面向對象的基本概念軟體的外部品質正確性健壯性可擴充性可複用性第一章面向對象的基本概念2.模組化模組化標準模組的可分解性(圖1.1)模組的可結合性(圖1.3)模組的可理解性(圖1.4)模組的連續(xù)性模組保護模組化原則語言模組單元資訊隱藏原則第一章面向對象的基本概念軟體複用代碼複用設計過程複用分析方案複用第一章面向對象的基本概念為什麼要面向對象程式中各種成分的特點:介面:極為易變功能:很易變過程執(zhí)行順序:很易變數(shù)據(jù):極為易變對象:最為穩(wěn)定面向功能的方法的缺陷:可擴充性、可維護性、複用性的問題。第一章面向對象的基本概念5.面向對象的基本概念面向對象的含義面向對象開發(fā)的含義面向對象的主題面向對象的含義面向對象是把軟體系統(tǒng)看成是一系列對象的集合對象包括數(shù)據(jù)結構,也包括行為面向對象的四個特性標識唯一性分類性多態(tài)性繼承性標識唯一性每一個對象都有一個唯一的標識通過標識找到對象對象的查找方法統(tǒng)一且獨立於對象的內容分類性具有相同數(shù)據(jù)結構和行為的對象構成一個類。類是一種抽象:它反映了與應用有關的重要性質,而忽略了一些無關的內容。多態(tài)性同一個操作可以是不同的類的行為繼承性類之間形成一種層次性的結構。父類的性質可以被子類繼承。減少了程式設計的重複性。代碼複用快速原型技術面向對象開發(fā)的含義建摸開發(fā)過程中真正有意義的成效來自於對象的概念,而不是實現(xiàn)。方法學分析系統(tǒng)設計對象設計實現(xiàn)面向對象開發(fā)的含義(續(xù))三種模型對象模型動態(tài)模型功能模型對象模型對象模型即描述對象的結構對象的唯一標識與其它對象的關係對象的屬性對象的操作動態(tài)模型動態(tài)模型描述與時間和操作次序有關的系統(tǒng)屬性:觸發(fā)事件事件序列事件狀態(tài)事件與狀態(tài)的組織動態(tài)模型關心的是控制。動態(tài)模型用狀態(tài)圖來表示。功能模型功能模型描述與值的變化有關的系統(tǒng)屬性:功能、映射、約束、依賴條件等功能模型用數(shù)據(jù)流圖表示。模型之間的關係對象模型描述了動態(tài)模型和功能模型中的數(shù)據(jù)結構;對象模型中的操作對應於動態(tài)模型中的事件和功能模型中的功能。動態(tài)模型描述了對象模型中對象喚醒、和動態(tài)模型中行為的喚醒的功能。功能模型說明說明對象模型中操作的含義和動態(tài)模型中的行為的意義,以及對象模型中約束的意義。面向對象的主題抽象封裝歸併數(shù)據(jù)與行為共用抽象強調實體的本質、忽略無關緊要的屬性決定對象時:研究對象的意義和行為繼承性強化了抽象的機制:避免過早地考慮細節(jié)問題封裝對象的內部實現(xiàn)細節(jié)對象獨立的外部性質分離實現(xiàn)細節(jié)與介面合併數(shù)據(jù)與行為歸併數(shù)據(jù)與行為類層次過程層次數(shù)據(jù)層次共用在同一個應用專案中共享:繼承在不同的專案中共享:類庫#include<iostream.h>voidmain(){ intj=3; cin>>j; cout<<“j=“<<j<<endl;}2.關於注釋/*comments*/編譯程序略去注釋對之間的內容//comments編譯程序略去注釋符後面的內容3.預處理#include#include<….h>在系統(tǒng)指定的目錄中尋找頭檔#include“…h(huán)”在系統(tǒng)當前目錄中尋找頭檔3.預處理#define#include<iostream.h>#defineHELLO"Hello,world!"voidmain(){ cout<<HELLO<<endl;}3.條件預處理#if,…#include<iostream.h>#defineDEBUG0voidmain(){ intj; j=5;#ifDEBUG cout<<"j="<<j<<endl;#endif}3.條件預處理#ifdef,…//2_5_4.cpp#include<iostream.h>#include"2_5_4.h"#include"2_5_4_1.h"voidmain(){ cout<<"x="<<x<<endl;}//2_5_4.h#defineXDEFintx=2;//2_5_4_1.h#ifndefXDEFintx=2;#endif4.數(shù)據(jù)類型的初步知識基本數(shù)據(jù)類型char,int,float,double,void修飾符signedunsignedlongshort4.數(shù)據(jù)類型的初步知識#include<iostream.h>voidmain(){ cout<<sizeof(char)<<endl; cout<<sizeof(int)<<endl; cout<<sizeof(float)<<endl; cout<<sizeof(double)<<endl; cout<<sizeof(longdouble)<<endl;}輸出結果:144884.數(shù)據(jù)類型的初步知識複合數(shù)據(jù)類型結構聯(lián)合位域枚舉類5.常量整型常量浮點常量字元常量字串常量6.變數(shù)變數(shù)的意義變數(shù)名匈牙利命名法:小寫字母開始表示變數(shù)類型其餘的名字表示變數(shù)的功能。例如;nCharacterCounter

整型變數(shù)、保存字元數(shù)。保留字不能作變數(shù)名變數(shù)的定義7.指針類型定義:類型*指針類型變數(shù)初始化同類型變數(shù)的左值:*p=&x;同類型指針變數(shù):p=q;動態(tài)分配的地址:int*p=new(int);int*p=malloc(sizeof(int));7.指針類型指針運算#include<iostream.h>voidmain(){ inti=1,j=2,k=3; int*p=&j; p=p+1; *p=*p+2;

cout<<i<<endl; cout<<j<<endl; cout<<k<<endl;}輸出結果:323#include<iostream.h>voidmain(){ char*st="Theexpenseofspirit"; intlen=0; char*p=st; while(*p++)len++; cout<<len<<":"<<st<<endl;}#include<iostream.h>voidmain(){ char*st="Theexpenseofspirit"; intlen=0; while(*st++)len++; cout<<len<<":"<<st<<endl;}8.引用類型定義intval=10;int&refVal=val;refVal+=2;//nowval=128.引用類型引用必須初始化不能再作其他變數(shù)的引用引用可以直接由一個右值去初始化,這時一個內部的臨時變數(shù)用於取得這個右值,然後引用使用這個臨時變數(shù)來進行初始化用不同類型的對象初始化時,同樣會由系統(tǒng)生成一個臨時變數(shù)。9.常量類型const必須被初始化定義後就不能被改變常量的地址不能被賦給一個指針constinta=3;int*p=&a;9.常量類型常量的指針:指針指向一個常數(shù)常量指針能再指向其他地址constint*p;intj,k;p=&j;p=&k;常量指針所指的對象不能通過這個常量指針來改變值constint*p;intj;p=&j;*p=*p+1;9.常量類型指針常量:指針是一個常量,但所指的變數(shù)未必是常量定義interrNum;int*constcurErr=&errNumb;可以改變指針常量所指的對象*curErr=1;*curErr=2;不可以改變指針常量curErr=&x;curErr=y;//Error例:程式2_11_1.10.枚舉類型枚舉類型是整型符號常量的集合。枚舉類型對象中的元素沒有記憶體地址。在默認的情況下第一個元素的值為0。每一個元素都可以被明確賦值。一個元素若沒有被明確賦值,則它的值是前一個元素的值加1。舉例11.數(shù)組類型一維數(shù)組:類型變數(shù)[數(shù)組大小];二維數(shù)組:類型變數(shù)[數(shù)組大小][數(shù)組大小];數(shù)組類型與指針的關係:&buf[0]與buf具有相同的意義。數(shù)組名不能運算:++buf是錯誤的。12.自定義類型名定義:typedef類型自定義類型;作用改善聲明過程:舉例2_15.cpp移植的方便typedefintADDRADDRa;ADDRb;typedeflongADDRADDRa;ADDRb;3.10類型轉換類型轉換:不改變二進位的結構,但用不同的方式解釋這些數(shù)據(jù)。3.10.1隱式類型轉換在算術運算式中,具有較大空間的數(shù)據(jù)類型成為最終結果轉換成的數(shù)據(jù)類型。例如:intval=3.14159;//轉換成3val+3.14159;//val先轉換成3.0,結果6.14159例intI=10;I*=2.3;cout<<I;運行結果:233.10.2顯式類型轉換在{intk;k=k+3.14159;}中將k轉化成double;計算運算式值將運算式的類型轉化成int在{intk;k=k+(int)3.14159;}中只有一次類型轉換void*的指針可以指向任何數(shù)據(jù),但不能直接引用void*的指針不能直接賦值給其他類型的指針void*用於對象類型未知或隨狀態(tài)而改變的情況3.10.2顯式類型轉換#include<iostream.h>voidmain(){ inti=10; //int*ip; void*vp; doubled=3.14159; //ip=&d;//cannotconvertfrom'double*'to'int*' vp=&d; cout<<*(double*)vp<<endl;}3.10.2顯式類型轉換{ void*vp; double*dp; doubled=3.14159; vp=&d; //dp=vp;//error:cannotconvertfrom'void*'to'double*' dp=(double*)vp;}3.11語句用分號結束一條語句最簡單的語句是“空語句”:;複合語句用花括弧括起來的一系列語句組成複合語句作未一個單一的單元出現(xiàn)在單一語句出現(xiàn)的任何地方複合語句不需要以分號終結3.12if語句語法結構:if(運算式)語句運算式必須放在括弧中。運算式為非0時,表示真,並執(zhí)行語句容易出現(xiàn)的錯誤1:經常忘了複合語句的花括弧3.12if語句#include<iostream.h>voidmain(){ inti=0; if(i) cout<<"first"<<endl; cout<<"second"<<endl;}輸出結果:second3.12if語句#include<iostream.h>voidmain(){ inti=0; if(i){ cout<<"first"<<endl; cout<<"second"<<endl; }}這個程式沒有輸出3.12if語句if-else語句:if(運算式) 語句1else

語句2語句1若不是複合語句則必須有分號

3.12if語句嵌套的if語句中else匹配的時離它最近的if語句:if(exp1) if(exp2) s1; else s2;

#include<iostream.h>voidmain(){ intk=0,n=1; if(k) if(n) cout<<"first"<<endl; else cout<<"second"<<endl;}//3_12_2.cpp沒有輸出#include<iostream.h>voidmain(){ intk=0,n=1; if(k){

if(n) cout<<"first"<<endl;}

else cout<<"second"<<endl;}輸出:second#include<iostream.h>#definesize5voidmain(){ intia[size]={3,1,2,9,1}; intminVal=ia[0]; intoccurs=1; for(inti=1;i<size;i++){ if(minVal==ia[i]) ++occurs; else

if(minVal>ia[i]){ minVal=ia[i]; occurs=1; } } cout<<"minVal="<<minVal<<endl; cout<<"occurs="<<occurs<<endl;}3.13switch語句格式:Switch(運算式){

caseexp1:語句1;break; …………….. caseexpn:語句n;break;}exp1,…expn都是常量運算式如果語句1,…,語句n後沒有break,則繼續(xù)執(zhí)行下一行語句。3.13switch語句Default語句Switch(運算式){

caseexp1:語句1;break; …………….. caseexpn:語句n;break; default:語句n+1;}3.14迴圈語句3.14.1while語句格式及意義while(運算式)語句只要運算式真,就執(zhí)行循環(huán)體語句。例3_14.cpp3.14.2

for語句格式for(init_statement;expr1;expr2)語句語義執(zhí)行init_statement;計算expr1;如果expr1非0,則執(zhí)行語句;否則結束for語句。執(zhí)行expr2;轉23.14.2

for語句for(;;)無限迴圈#include<iostream.h>voidmain(){ inti=0; for(;;){ if(i>5)break; cout<<i<<endl; i++; }}3.14.3

do語句格式do

語句while(expr);#include<iostream.h>voidmain(){ inti=0; do cout<<i++<<endl; while(i<5);}4.1成員變數(shù)和成員函數(shù)4.1類的定義定義類:classStack{ …};定義類並說明對象classStack{ …}obj1,obj2;4.1.2成員變數(shù)1.與聲明變數(shù)的方式相同聲明中不允許進行初始化賦值classStack{ int*lst; intmax_size; intnb_elements;};classStack{ int*lst; //error intmax_size=0; intnb_elements;};4.1.2成員變數(shù)3.成員變數(shù)可以使任何類型classStack{ int*lst; intmax_size; intnb_elements; Stack*s;};classStackofStack{ inttopStack; Stackstackstorage[5];};4.1.2成員變數(shù)4.提前聲明:一個類提前聲明之後,這個類的對象指針、引用可以作為另一個類的成員變數(shù)。

classStack;classStackofStack{ inttopStack; Stack*stackstorage;};

但這個類的對象不能作另一個類的成員變數(shù)。4.1.3成員函數(shù)在定義體外定義4_1_2.cppclassStack{ intempty(); voidpop(); inttop(); voidpush(int);};intStack::empty(){return(nb_elements==0);}4.1.3成員函數(shù)在定義體內定義4_1_2.cppclassStack{ intempty(){return(nb_elements==0);} voidpop(); inttop(); voidpush(int);};4.1.4資訊隱藏原則:將類的功能描述部分作為共有部分介面提供給用戶;將數(shù)據(jù)的具體表示、具體實現(xiàn)作為私有部分隱藏起來。成員函數(shù)友元派生類其他privateYNNprotectedYYNpublicYYY4.1.4資訊隱藏例共有部分-私有部分intempty();voidpop();inttop();voidpush(int);int*lst;intmax_size;intnb_elements;4.1.5對象與類類對象對象的說明類對象1,對象2,對象n;4_1_2.cpp4.1.6const成員函數(shù)聲明為const的對象是不能被賦值的聲明為const的對象不能隨便調用任意的成員函數(shù)聲明為const的對象只能調用聲明為const的成員函數(shù)const的成員函數(shù)不能改變成員變數(shù)4.2構造函數(shù)與析構函數(shù)構造函數(shù)4.2構造函數(shù)和析構函數(shù)4.2.1對象的初始化構造函數(shù)用來在聲明對象時,初始化成員變數(shù)。4_2_1.cpp如果定義了構造函數(shù),則在聲明對象時所帶參數(shù)類型必須與某一個構造函數(shù)的的參數(shù)類型一致。4_2_1.cpp如果沒有定義構造函數(shù),則在聲明對象時不帶參數(shù)。4_2_0.cpp4.2.2構造函數(shù)的定義構造函數(shù)不允許指明返回類型,也不允許返回一個值。構造函數(shù)的名字必須與類的名字一樣。構造函數(shù)可以重載:有多種定義,每一種定義的參數(shù)表不一樣。聲明對象時參數(shù)類型必須與一個構造函數(shù)的參數(shù)類型一致。構造函數(shù)一般說明為public。例4_2_2.cpp構造的調用:明確調用方式Strings1=String(“rose”);Strings2=String(3);Strings3=newString(“rose”);簡化調用方式Strings3(“rose);Strings4=“rose”;例4_2_3.cpp用無參數(shù)構造函數(shù)初始化對象不定義任何構造函數(shù)定義無參數(shù)的構造函數(shù)例:4_2_4.cppStrings();不是聲明無參數(shù)的對象,而是不帶參數(shù)的返回類型String型對象的函數(shù)。4.2.3析構函數(shù)4.2.3.1對象的生存期對象的生存期4_2_3_1.cpp一個對象在退出作用域時,系統(tǒng)要回收其空間。在退出對象指針時,如果沒有調用delete則不會釋放指針所指的空間。4.2.3.2系統(tǒng)回收空間LenStrLenStrLenStr{deletestr;}{}LenStr系統(tǒng)回收垃圾空4.2.3.3析構函數(shù)格式:~類名();析構函數(shù)不帶參數(shù),沒有返回值。例4_2_3_2.cpp4.2.3.4顯式調用析構函數(shù)如果只想執(zhí)行析構函數(shù)中的執(zhí)行的操作,而不釋放對象的空間,則可以顯式調用析構函數(shù)。pb->String::~String();執(zhí)行析構函數(shù)中的執(zhí)行的操作。pb->~String();執(zhí)行系統(tǒng)的析構函數(shù),釋放對象的空間。4.2.4類/對象數(shù)組定義constsize=16Stringtbl[size];String*tbl=newString[size];訪問數(shù)組對象tbl[I].display();4.2.4類/對象數(shù)組初始化Strings[]={“rose”,“sbeef”};Stringt[]={String(),String(3);String(“rose”)};刪除delete[2]s;delete[3]t;4.2.5對象成員構造函數(shù)的執(zhí)行次序:對象成員的構造函數(shù)先初始化,然後才是包含它的類的構造函數(shù)。有多個對象成員時,按照在類的定義中聲明的次序初始化。4_2_5_1.cpp對象成員的初始化參數(shù)由初始化表提供。初始化表只能出現(xiàn)在構造函數(shù)的定義體中,不能出現(xiàn)在構造函數(shù)的聲明中。(MSVC++沒有這個限制。)4.2.5對象成員const成員必須在成員初始化表中初始化。4_2_5_2.cpp。成員對象的初始化參數(shù)可以是同一類型的另一個對象。4_2_5_3.cpp。多層成員對象初始化的次序。4_2_5_3.cpp。4.2.6成員初始化通過另一個對象初始化編譯器定義的拷貝函數(shù)X::X(const&X);String::String(const&String&s){ len=s.len; str=s.str;}//淺拷貝4_2_6.cpp4.2.7構造函數(shù)X::X(const&X)String::String(constString&s){ len=s.len; str=newchar[len+1]; strcpy(str,s.str);};//深拷貝4_2_7.cpp4.3靜態(tài)成員變數(shù)和靜態(tài)成員函數(shù)某個類的所有對象都共同訪問同一個變數(shù)。全局變數(shù)的缺點靜態(tài)成員變數(shù)類的所有對象都共用靜態(tài)成員變數(shù)圖4.7聲明:static類型變數(shù)初始化:類型類名::變數(shù)=初始值;初始化時不加static初始化時不用加private、public、protected初始化時用域作用符::說明所屬類。4.4內聯(lián)函數(shù)使c++編譯器在函數(shù)調用處以代碼體內聯(lián)來替換對函數(shù)的調用。4.5友元成員函數(shù)派生類其他privateYNNprotectedYYNpublicYYY4_5_1.cpp4.6對象和動態(tài)對象4.6.1this指針一個類所有的對象的成員變數(shù)除了靜態(tài)變數(shù)外都有獨立空間,但同一個類的所有對象成員共用同一組成員函數(shù)。一個對象調用自己的成員函數(shù)時,將this指針傳遞給這個成員函數(shù),這個this指針指向這個對象。例:4_6_1_1.cpp4.6.1this指針成員函數(shù)翻譯成非成員函數(shù)voidStack::empty(){ return(nb_elements==0);}voidempty__Stack(Stack*this){ return(this->nb_elements==0);}成員函數(shù)翻譯成非成員函數(shù)voidStack::push(intelements){ if(nb_elements<max_size) lst[nb_elements++]=elements;}voidpush__Stack(Stack*this,intelements){ if(this->nb_elements<this->max_size) lst[this->nb_elements++]=elements;}連續(xù)操作,返回this指針4_6_1_2.cpp4.6.2動態(tài)對象用new代替malloc、alloc等用delete代替free變數(shù)指針=new類型;變數(shù)指針=new類型(初始值);變數(shù)指針=new類型[size];變數(shù)指針=new類型[size][size];delete變數(shù)指針;delete[size]變數(shù)指針;初始化與數(shù)組對象用new分配一個對象時,可以直接初始化。用new分配一個對象數(shù)組時,不可以直接初始化,並且對象必須有一個無參數(shù)構造函數(shù)。例:4_6_2_1.cpp例:4_6_2_2.cpp例:4_6_2_3.cpp5.1結構5.1.1結構的定義與結構變數(shù)的聲明structexample{inta; floatb;}structexamplee1,e2;typedefstructexample{inta; floatb;}EXAMPLE;EXAMPLEe1,e2;5.1結構5.1.1結構的定義與結構變數(shù)的聲明structexample{inta; floatb;}examplee1,e2;structexamplee3,e4;5.1.2結構作為類結構中也可以引入成員函數(shù)在缺省的情況下結構的成員是public例:5_2_1.cpp5.2.1聯(lián)合作為類聯(lián)合的成員變數(shù)共用記憶體同一個單元在缺省的情況下,聯(lián)合成員是公有的聯(lián)合可以包含成員函數(shù)聯(lián)合不能繼承其他的類聯(lián)合不能有序函數(shù)靜態(tài)變數(shù)不能是聯(lián)合如果有構造、析構函數(shù),則對象不能是聯(lián)合的成員例:5_2_1_1.cpp5.2.2匿名聯(lián)合匿名聯(lián)合不含類型名變數(shù)不能被說明為這類聯(lián)合聯(lián)合的成員變數(shù)要共用同一個單元聯(lián)合的變數(shù)直接引用例:5_2_2_1.cpp匿名聯(lián)合不能有成員函數(shù)匿名聯(lián)合不能有private,protected全局匿名聯(lián)合必須是靜態(tài)的。6.1函數(shù)函數(shù)的聲明[inline][返回類型]函數(shù)名(形式參數(shù)表);形式參數(shù)表:[類型[變數(shù)名]{,類型[變數(shù)名]}]例:voidf(int);intgcd(int,int);inlineintmin(intj,intk);6.1.1遞歸一個函數(shù)如果直接或間接地調用自身稱為遞歸函數(shù)。例6_1_1_1.cpp6.1.2內聯(lián)函數(shù)內聯(lián)函數(shù)與直接代碼比較的優(yōu)點可讀性容易修改類型檢查複用6.1.3強類型檢查所有函數(shù)調用的參數(shù)表和返回值都要進行類型檢查。如果一個實參類型與函數(shù)原型聲明的形式參數(shù)不匹配,則首先使用隱式類型轉換,若隱式類型轉換無法進行,或參數(shù)個數(shù)不符,則給出編譯錯誤。6.1.4返回值數(shù)組類型、函數(shù)類型不能作為返回類型。數(shù)組類型的指針、函數(shù)類型的指針可以作為返回類型。默認的返回類型是int。6.1.5函數(shù)參數(shù)表參數(shù)表語法結構intfork();intfork(void);等價。函數(shù)聲明中可以只出現(xiàn)類型不出現(xiàn)參數(shù)名。有參數(shù)名可以增加可讀性。函數(shù)定義中必須出現(xiàn)類型和出現(xiàn)參數(shù)名。參數(shù)個數(shù)不定的參數(shù)表例6_1_5_1.cpp有缺省值參數(shù)有缺省值參數(shù)必須放在最後6.1.6參數(shù)傳遞傳值參數(shù)傳遞將實際參數(shù)的右值複製到形式參數(shù)的存儲空間。不適合傳遞大量數(shù)據(jù)不適合返回計算結果指針參數(shù)傳遞引用參數(shù)例:6_1_6_1.CPP6.1.7引用參數(shù)參數(shù)傳遞方式類似與指針參數(shù)傳遞程式書寫方式類似與傳值參數(shù)傳遞6.1.8數(shù)組參數(shù)一下三種聲明等價:voidf(int*);voidf(int[]);voidf(int[10]);編譯器和函數(shù)都不檢查數(shù)組參數(shù)的個數(shù)voidf(int*,intsize);voidf(int[],intsize);voidf(int[10],intsize);6.1.8數(shù)組參數(shù)多維數(shù)組參數(shù)

intf(intmatrix[][10],introwSize);intf(int(*matrix)[10],introwSize);6.1.9作用域檔域局部域、局部塊域類域域操作符:::使程式可以處理被隱藏的外部變數(shù)外部變數(shù)靜態(tài)外部變數(shù)6.1.10局部域將局部變數(shù)的地址傳出是一個嚴重的錯誤:intf(inta,intb){ return&a;}靜態(tài)局部變數(shù)寄存器型局部變數(shù)作業(yè)建立一個保存整數(shù)的環(huán)形佇列存放數(shù)據(jù)讀取數(shù)據(jù)。。。。。6.1.6參數(shù)傳遞傳值參數(shù)傳遞將實際參數(shù)的右值複製到形式參數(shù)的存儲空間。不適合傳遞大量數(shù)據(jù)不適合返回計算結果指針參數(shù)傳遞引用參數(shù)例:6_1_6_1.CPP6.1.7引用參數(shù)參數(shù)傳遞方式類似與指針參數(shù)傳遞程式書寫方式類似與傳值參數(shù)傳遞6.1.8數(shù)組參數(shù)一下三種聲明等價:voidf(int*);voidf(int[]);voidf(int[10]);編譯器和函數(shù)都不檢查數(shù)組參數(shù)的個數(shù)voidf(int*,intsize);voidf(int[],intsize);voidf(int[10],intsize);6.1.8數(shù)組參數(shù)多維數(shù)組參數(shù)

intf(intmatrix[][10],introwSize);intf(int(*matrix)[10],introwSize);6.1.9作用域檔域局部域、局部塊域類域域操作符:::使程式可以處理被隱藏的外部變數(shù)外部變數(shù)靜態(tài)外部變數(shù)6.1.10局部域將局部變數(shù)的地址傳出是一個嚴重的錯誤:intf(inta,intb){staticintk; return&a;}靜態(tài)局部變數(shù)寄存器型局部變數(shù)6.2.1動態(tài)分配空間例6_2_1.cppIntArray中的ia所指的空間是動態(tài)分配的,ia本身是靜態(tài)分配的。在局部域中的對象進入局部域時分配空間,推出時系統(tǒng)自動返回空間。動態(tài)分配的空間必須顯示地回收空間。6.2.2一個鏈接表的例子6_2_2_1.cpp6.2.3函數(shù)重載兩個及兩個以上不同的函數(shù)共用一個函數(shù)名,利用函數(shù)的參數(shù)表來區(qū)別。intmax(int,int);doublemax(double,double);complex&max(complex&,complex);intimax(int,int);doubledmax(double,double);complex&cmax(complex&,complex);6.2.3函數(shù)重載參數(shù)表和函數(shù)名相同的兩個函數(shù)被認為是重定義。不適合函數(shù)重載的情況不同的函數(shù)的操作沒有類似的地方重載函數(shù)的調用完全匹配參數(shù)轉換引用參數(shù)類型的匹配類型必須完全匹配多個參數(shù)的調用:6_2_3_7_1.cpp參數(shù)的隱含值重載與作用域重載new6.2.4指向函數(shù)的指針函數(shù)類型指針返回類型(*函數(shù)指針名)(參數(shù)表);函數(shù)名同時也表示指向該函數(shù)的指針若voidf(),則f與&f具有相同的類。初始化與賦值voidf(){cout<<"f:"<<endl;}voidg(){cout<<"g:"<<endl;}void(*pf)();voidmain(){ pf=f;pf(); pf=g;pf();}函數(shù)指針數(shù)組Int(*pfArray[10])(int);例:6_2_4_1.cpp函數(shù)指針數(shù)組初始化void(*_new_handler)()指向無返回參數(shù)無參數(shù)的函數(shù)的指針。當new分配失敗時,測試該指針是否指向了一個函數(shù),如果它為被賦值,則new返回0,否則調用該指針指向的函數(shù)。構造函數(shù)調用順序基類的構造函數(shù)內部成員對象的構造函數(shù)派生類的構造函數(shù)析構函數(shù)的調用順序與構造函數(shù)調用順序相反函數(shù)重載時參數(shù)的傳遞首先檢查是否由完全匹配在檢查是否有通過標準轉換的匹配通過標準轉換後有多種匹配,則報告ambiguous匹配錯誤。例:6_3_1.cpp全局靜態(tài)變數(shù)全局靜態(tài)變數(shù)的作用外部變數(shù)靜態(tài)局部變數(shù)、局部塊域例:6_3_3.cpp值參例:6_3_4.cpp#include<iostream.h>voidf(inti){ cout<<i<<endl;}voidmain(){ inti=1;f(i);}8:f(i);004010CFmoveax,dwordptr[ebp-4]004010D2pusheax004010D3call@ILT+15(f)(00401014)004010D8addesp,49:}指針參數(shù)#include<iostream.h>voidf(int*i){ cout<<i<<endl;}voidmain(){ inti=1;f(&i);}8:f(i);004010CFleaeax,[ebp-4]004010D2pusheax004010D3call@ILT+35(f)(00401028)004010D8addesp,49:}引用型參數(shù)#include<iostream.h>voidf(int&i){ cout<<i<<endl;}voidmain(){ inti=1;f(i);}8:f(&i);004010CFleaeax,[ebp-4]004010D2pusheax004010D3call@ILT+30(f)(00401023)004010D8addesp,49:}用引用返回值例:6_3_5.cpp#include<iostream.h>floattemp;floatfn1(floatr){ temp=r*r*(float)3.14; returntemp;}float&fn2(floatr){ temp=r*r*(float)3.14; returntemp;}voidmain(){ floata=fn1(5.0); //float&b=fn1(5.0); floatc=fn2(5.0); float&d=fn2(5.0); cout<<a<<endl; //cout<<b<<endl; cout<<c<<endl; cout<<d<<endl;}floata=fn1(5.0);fn1r5.0臨時變數(shù)atemp78.5floatc=fn2(5.0);fn1r5.0臨時變數(shù)ctemp78.515:floatc=fn2(6.0);00401118push40C00000h0040111Dcall@ILT+20(fn2)(00401019)00401122addesp,400401125moveax,dwordptr[eax]00401127movdwordptr[ebp-8],eaxFloat&d=fn2(5.0);fn1r5.0臨時變數(shù)d&temptemp78.516:float&d=fn2(7.0);0040112Apush40E00000h0040112Fcall@ILT+20(fn2)(00401019)00401134addesp,400401137movdwordptr[ebp-0Ch],eax7.1類的層次概念層次與複用成員的繼承類的兩種使用方法:實例化使用繼承使用將概念和實現(xiàn)轉變成類層次派生類是基類的具體化派生類是基類的延遲定義派生類是基類的組合7.2單繼承定義格式class派生類名:[訪問控制]基類名{

成員列表}訪問控制privateprotectedpublic公有基類基類的公有成員等價於派生類的公有成員。派生類的對象及其成員函數(shù)可以訪問基類的公有成員。保護基類基類的公有成員等價於派生類的保護成員。派生類的成員函數(shù)可以訪問基類的公有成員。派生類的對象不可以訪問基類的公有成員。私有基類基類的公有成員等價於派生類的私有成員。只有派生類的成員函數(shù)可以訪問基類的私有成員。部分公開使基類部分公有成員成為派生類的公有成員。base::成員名;在派生類中訪問聲明不允許對基類成員中私有成員進行訪問。例:7_2_1_2.cpp基類性質繼承性質派生類性質publicpublicpublicprotectedpublicprotectedprivatepublic不能訪問publicprotectedprotectedprotectedprotectedprotectedprivateprotected不能訪問publicprivateprivateprotectedprivateprivateprivateprivate不能訪問7.2.2成員訪問控制公有基類基類成員對基類對象的可見性:公有成員可見,其他不可見?;惓蓡T對派生類的可見性:公有成員和保護成員可見,私有成員不可見?;惓蓡T對派生類對象的可見性公有成員可見,私有成員和保護成員不可見。例:7_2_2.cppclassbase{ private:inti1; protected:intj1; private:intf1();};classdrv:publicbase{ private:inti2; protected:intj2; public:intf2();};Voidmain(){drvd1;}保護基類基類成員對基類對象的可見性:公有成員可見,其他不可見?;惓蓡T對派生類的可見性:公有成員和保護成員可見,私有成員不可見。公有成員和保護成員對派生類的派生類的成員可見基類成員對派生類對象的可見性所有成員都不可見私有基類基類成員對基類對象的可見性:公有成員可見,其他不可見?;惓蓡T對派生類的可見性:公有成員和保護成員可見,私有成員不可見。所有成員對派生類的派生類的成員不可見基類成員對派生類對象的可見性所有成員都不可見7.2.3構造函數(shù)參數(shù)的傳遞派生類名::派生類名(派生類參數(shù)表):基類名(基類參數(shù)表){

派生類初始化代碼

}基類沒有構造函數(shù)或構造函數(shù)沒有參數(shù)基類有構造函數(shù)且構造函數(shù)都有參數(shù)構造函數(shù)調用順序基類的構造函數(shù)內部成員對象的構造函數(shù)派生類的構造函數(shù)析構函數(shù)的調用順序與構造函數(shù)調用順序相反例:7_2_3_1.cpp例子7_2_4_1.cpp7_2_4_2.cpp多繼承的概念繼承所有基類的成員變數(shù)和成員函數(shù)inta;intb;intc;inta;intx;inty;inta;intb;intc;inta;intx;inty;intk;多繼承的定義格式:Class派生類:訪問控制基類[,訪問控制基類]{定義體}當有多個同名的繼承成員時,可以用域說明符號::來限定。例:7_3_0_1.cpp構造函數(shù)的調用順序基類的構造函數(shù)成員對象的構造函數(shù)派生類的構造函數(shù)例:7_3_0_1.cpp析構函數(shù)的調用順序派生類的析構函數(shù)成員對象的析構函數(shù)基類的析構函數(shù)多重公共基類parentprivate1private2derived_1:virtulparentprivate1private2private3derived_:virtulparent2private1private2private4derived_1_2private1,private2,private3,private4,private12例:7_3_2_1.cpp虛基類虛基類的意義在繼承路徑上,所有虛基類的成員變數(shù)只有一份。虛基類的構造函數(shù)必須由最新派生出來的類負責初始化虛基類的構造函數(shù)先於非虛基類的構造函數(shù)執(zhí)行。例:若定義classL{...};classA:virtualL{...};classB:virtualL{...};classC:B,A{...};

則在類C中只有一份類L的成員變數(shù)。例:7_2_3_2.cpp虛基類parentprivate1private2derived_1:virtualparentprivate1Private2private3derived_2:virtualparentprivate1Private2private4derived_1_2private1,private2,private3,private4,private12例:7_3_2_2.cpp二義性問題(1)classL{public:voidf();};classA{public:intf();};classB:publicL,publicA{public: voidg(){f();}};這個例子中g()的訪問f()具有二義性,報告語法錯誤??梢訪::f();或A::f();的形式訪問,即用類名加以限制。二義性問題(2)二義性檢查在訪問控制之前,因此當不同的基類成員中有相同的成員函數(shù)名時,就會出現(xiàn)二義性,及時由於訪問控制的限制,只有一個成員可見。如果A是B的基類,類A與B都有成員函數(shù)f(),則稱B::f()支配A:f()。有支配關係的兩個名字不會出現(xiàn)二義性。7_3_3_1.cpp7.3.4實例7_3_4_1.cppdata_recStaff:virtualdata_recstudent:virtualdata_recstudent_staffprofessorstudentlast_name;first_namestreet_address;citystate;zip;majorid_number;level;Stafflast_name;first_namestreet_address;citystate;zip;depthourly_wage;運算符重載例:8_2_1.cpp自定義的類的運算往往用函數(shù)來實現(xiàn)運算符重載l

運算符重載的目的:擴充語言的功能,即將運算符擴充到用戶定義的類型上去。l

除了.、.*、::、?、:其他都可以重載。l

delete、new、指針、引用也可以重載。l

運算符函數(shù)可以定義為內聯(lián)函數(shù)。l

用戶定義的運算符不改變運算符的優(yōu)先次序。l

不可以定義系統(tǒng)定義的運算符集之外的運算符。不能改變運算符的的語法結構。雙目運算符重載8.2.1雙目運算符重載可進行重載的雙目運算符:*/%+-<<>><><=>=!=&^|&&||雙目運算符重載的聲明格式:class類名{類型operator運算符(參數(shù));}雙目運算符重載的定義格式: 類型類名::operator運算符(參數(shù));this指針:一個對象調用它的成員函數(shù)時,系統(tǒng)會傳給它一個指針this,指向對象自己。雙目重載時,this指向運算符左邊的對象。例:8_2_1_1.cpp友元運算符重載聲明:friend類型operator運算符(參數(shù)表);定義:類型operator運算符(參數(shù)表){……};例:8_2_1_2.cpp成員與友元運算符函數(shù)的區(qū)別參數(shù)個數(shù)不同this指針8_2_1_3.cpp8_2_1_4.cpp單目運算符重載不帶參數(shù)的成員函數(shù)8_2_2_2.cpp8_2_2_4.cpp帶有一個參數(shù)的友元函數(shù)8_2_2_1.cpp參數(shù)必須是引用不繼承=,繼承+8_2_2_3.cpp幾個特殊的運算符號重載[]重載8_2_3_1.cppX[k]解釋為X.operator[](k)()重載8_2_3_1.cppX(arg)解釋為X.operator()(arg)虛函數(shù)在選擇要調用的函數(shù)時有幾種方法來選擇根據(jù)參數(shù)的特徵來選擇:同一個類可以用同一個函數(shù)名來定義不同的多個函數(shù),它們用參數(shù)類型來區(qū)分。根據(jù)作用域來確定:每個函數(shù)都有它的可見的區(qū)域。根據(jù)類的對象來確定:每個對象都有自己實現(xiàn)的函數(shù)的版本。前期聯(lián)編與後期聯(lián)編前期聯(lián)編:在編譯時刻就能夠確定要調用的函數(shù)後期(動態(tài))聯(lián)編:在運行時刻才能確定要調用的函數(shù)為什麼需要虛函數(shù)一個類中的多個函數(shù)的名字可以有相同的名字,但是它們的函數(shù)特徵(參數(shù)類型與個數(shù))必須不同

基類的函數(shù)名與派生類的函數(shù)可以同名且函數(shù)特徵(參數(shù)類型與個數(shù))完全一致,派生類的對象會調用自己的函數(shù)??梢砸砸粋€指向基類對象的指針去訪問指向派生類的對象,在前期聯(lián)編的情況下,調用基類的成員函數(shù),只在動態(tài)聯(lián)編的情況下會調用派生類的成員函數(shù)。

基類與派生類間指針轉換的幾條原則指向派生類對象的指針無需進行顯示轉換就能賦給基類對象:parent*p;derived*d;p=d;基類對象的指針不進行顯示轉換就不能賦給派生類對象:parent*p;derived*d;d=p;是錯誤的。基類對象的指針進行顯示轉換後就能賦給派生類對象:parent*p;derived*d;d=(derived*)p。不能以一個指向派生類對象的指針去訪問基類的對象,但可以以一個指向基類對象的指針去訪問指向派生類的對象。若沒有使用強制類型說明,基類對象指針不能訪問在派生類中定義的成員。

指向基類對象的指針可用於指向任何從它派生出來的類對象。8_3_1_4.cpp虛函數(shù)的意義告訴編譯程序確定一個對象的指針所指的成員函數(shù)的問題應等到運行時刻,檢查這個指針到底指向哪個對象,基類對象還是派生類對象,調用指針實際所指的對象的成員函數(shù)。例:8_3_1_1.cpp例:8_3_1_2.cpp例:8_3_1_3.cpp關於虛函數(shù)的一些說明一旦一個函數(shù)定義為虛函數(shù),那麼無論它傳下多少層,都將保持為虛函數(shù)。虛函數(shù)必須是定義它的類的成員函數(shù)。虛函數(shù)與派生類中覆蓋它的函數(shù)有類型匹配,即返回類型、參數(shù)個數(shù)、類型都相同。虛函數(shù)的訪問控制規(guī)則由它聲明時的規(guī)則確定?;惖闹羔樋梢栽L問派生類的函數(shù),甚至是派生類的私有函數(shù)。8_3_1_5.cpp構造函數(shù)不能為虛函數(shù),析構函數(shù)可以定義為虛函數(shù)。8_3_1_6.cpp含有虛函數(shù)的類的實例?;惖臉嬙旌瘮?shù)先於派生類的構造函數(shù)調用,在對象構造出來之前,派生類中定義的虛函數(shù)不可被該類的對象啟動。8_3_1_7.cpp純虛函數(shù):在第一次聲明時不提供定義,例如classA{…;virtualvoidf()=0;…};抽象類:一個類如果至少有一個純虛函數(shù)就稱為抽象類。抽象類不能實例化,即它不能建立對象。8_3_1_8.cpp8.3.2實例有限狀態(tài)機:8_3_2_1.cpp定義一個parent類,其他狀態(tài)定義為parent的子類。指向子類的parent類的指針可以訪問子類的轉換函數(shù)。8_3_2_2.cpp8_3_2_3.cpp作業(yè)

一個三口之家,大家都知道父親會開車、母親會唱歌。但是父親還會修電視機,只有家裏人知道。小孩既會開車又會唱歌又會修電視機。母親瞞著任何人在外面做小工補貼家用。此外

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論