《面向對象程序設計》PPT課件
《《面向對象程序設計》PPT課件》由會員分享,可在線閱讀,更多相關《《面向對象程序設計》PPT課件(173頁珍藏版)》請在裝配圖網上搜索。
1、緒 論,面向對象程序設計: 通過增加軟件可擴充性和可重用性來改善并提高程序員的生產能力,并控制維護軟件的復雜性和軟件維護的開銷,OOP:具有結構化程序設計的一切優(yōu)點 將數(shù)據和對數(shù)據的操作放在一起,作為一個相互依存、不可分割的一個整體,抽象成一種新的數(shù)據類型類 兩大技術(兩個重要原理) 數(shù) 據 抽 象 信 息 隱 藏,自行車類: (1)數(shù)據:尺寸、顏色、材料等(屬 性) (2)操作:轉彎、移動、修理等(操 作) 每一輛具體的自行車就是屬于自行車類的一個對象,OPP支持的軟件開發(fā)策略 編寫可重用代碼 編寫可維護的代碼 共享代碼 精化已有的代碼,OOP的五
2、大基本概念 1對象(Object):數(shù)據及可以對這些數(shù)據施加的操作結合在一起所構成的獨立實體的總稱,是計算的最基礎的構造塊 成員變量(數(shù)據):表明對象的狀態(tài) 成員方法(操作):表明對象的行為 一組成員變量和相關的方法集合,2類(Class):對一組具有相同數(shù)據和相同操作的對象的描述(定義),依據共同的行為將有關對象進行的一種分組 類中所有對象共享類中所有共同的特性 類是對象的抽象 程序中:只有類 對象是類的實例 運行時:只有對象,3實例(Instance):由某個特定類所描述的一個對象 通常,對象和類的實例是同義詞,4消息(Message):要求某個對象執(zhí)行類中所定義的某個操作的規(guī)格說明,,5
3、方法(Method):對象所能執(zhí)行的操作 它是類中定義的函數(shù),描述對象執(zhí)行操作的算法,即響應消息的方法,OOP方法學的四大要點 1認為世界由各種對象(object)組成,任何事物都是對象,是某個對象類(class)的實例(instance) 2把所有對象都劃分成各種對象類,每個對象類都定義了一組方法(method),即允許施加于該類對象上的各種操作,3對象之間除了互相傳遞消息的聯(lián)系之外,再沒有其他聯(lián)系 4對象類將按照“類”、“子類”與“父類”的關系構成一個層次結構的系統(tǒng),OOP的三大核心特征 封裝性(Encapsulation) 繼承性(Inheritance) 多態(tài)性(Pol
4、ymorphism),1封裝性:數(shù)據和加工處理該數(shù)據的方法緊密結合在一起構成黑匣子的整體 對私有數(shù)據不能執(zhí)行該對象的成員函數(shù)之外的任何其它函數(shù),2繼承性:一個類直接繼承其父類的全部描述(數(shù)據和函數(shù)) 繼承具有傳遞性: 若類C繼承類B,類B繼承類A,則類C繼承類A 類實際上繼承了類等級中在其上層的全部基類(父類)的所有描述,,繼承方式分類(一) 取代繼承:徒弟學會全部技術,可以取 代師傅 包含繼承:水果是對象,蘋果是特殊的 水果,包含了水果具有的所 有特征 受限繼承:駝鳥是對象鳥的一個特例, 它不能繼承鳥會飛的特征 特化繼承:工程師是一類特殊的人,比
5、 一般人具有更多的特有信息,繼承方式分類(二) 單繼承:一個類只有一個父類時 (樹結構) 多繼承:一個類可有多個父類時 (圖結構),3多態(tài)性:在類等級的各層中共享(公用)一個行為(函數(shù))的名字,而類等級中的每個類卻各自按照自己的需要來實現(xiàn)這個行為 一個名字,多種語義 相同界面,多種實現(xiàn),函數(shù)重載表達了最簡單的多態(tài)性 void f( int, int, char ); void f( char, float ) ; void f( int, int ) ; void f( float, float ); 參數(shù)數(shù)量、類型、順序不同,函數(shù)體也可以完全不同,OO
6、P的兩個重要原理 1數(shù)據抽象:通過從特定的實例中抽取共同性質以形成一般化的概念的過程 強調部分特性(用戶所關心的特性) 忽略其他特性(用戶不關心的特性) 用戶:只關心做什么 , 不關心怎么做 OOP技術比任何一種編程技術都更強調抽象在軟件開發(fā)中的重要性,2行為共享: (1)實體(模塊)的外部接口稱為行 為 (2)行為共享允許多個實體(模塊) 具有相同的接口集 (3)行為共享增強系統(tǒng)的靈活性 (4)行為共享增強系統(tǒng)的抽象,流 流是一個抽象的概念,它指的是數(shù)據從一個源(source)到一個終點(sink)的流動 c++提供四個預定義的開放流,cin: 標準輸入,通常指鍵盤,對應于
7、c中的stdin, cout:標準輸出,通常指屏幕,對應于 c中的stdout cerr:標準錯誤輸出,通常指屏幕,對 應于c中的stderr clog:cerr的全緩沖版(c中沒有等價 的)cerr:無緩沖 clog:有緩沖,1const 比較 # define pai 3.1415927 預處理中的宏定義 const float pai=3.1415927 或者 float const pai=3.1415927 常量修飾符 pai是類型化的,有地址,可用指針指向它,,定義或說明一個常數(shù)組可采用如下格式: const 或者 const int const a
8、5=1, 2, 3, 4, 5;,,常對象是指對象常量,定義格式如下: const 或者 const 定義常對象時,同樣要進行初始化,并且該對象不能再被更新,const與指針的組合使用,下面定義的一個指向字符串的常量指針: char * const prt1 = stringprt1; 其中,ptr1是一個常量指針。因此,下面賦值是非法的。 ptr1 = stringprt2; 而下面的賦值是合法的: *ptr1 = m; 因為指針ptr1所指向的變量是可以更新的,不可更新的是常量指針ptr1所指的方向(別的字符,下面定義了一個指向字符串常量的指針: const char * ptr2 = s
9、tringprt1; 其中,ptr2是一個指向字符串常量的指針。ptr2所指向的字符串不能更新的,而ptr2是可以更新的。因此, *ptr2 = x; 是非法的,而: ptr2 = stringptr2; 是合法的。,(1)指向常量的指針: 指向的常量不能改變 1)const char * pc=”asdf”;//指向常量 的指針 pc3= a; //錯 pc=”ghik”; //對 2)const char * step3 =”left”,”right”,”top”; step 2=”skip”; //對 step 21=i
10、; //錯,(2)常指針:指針本身不能改變,指向的對象可以改變 1)char * const pc=”asdf”; //常指針 pc3= a; //對 pc =”ghik”; //錯 2)char * const step 3 =“l(fā)eft”,”right”,”top”; step2=”skip”; //錯 step21=i; //對,(3)指向常量的常指針:指針本身及指向的對象均不能改變 const char * const pc=”asdf”; //指向常量 的常指針 pc3= a; //錯 pc
11、=”ghik”; //錯,注意: (1)const總是修飾緊隨其后的東西 (2)指向常量的指針不能賦給一般 的指針,一般的指針可以賦給 指向常量的指針,2. 常引用 使用const修飾符也可以說明引用,被說明的引用為常引用,該引用所引用的對象不能被更新。其定義格式如下: const 在實際應用中,常指針和常引用往往用來作函數(shù)的形參,這樣的參數(shù)稱為常參數(shù)。 在C++面向對象的程序設計中,指針和引用使用得較多,其中使用const修飾的常指針和常引用用得更多。使用常參數(shù)則表明該函數(shù)不會更新某個參數(shù)所指向或所引用的對象,這樣,在參數(shù)傳遞過程中就不需要執(zhí)行拷貝初始化構造函數(shù),
12、這將會改善程序的運行效率。,#include const int N = 6; void print(const int *p, int n); void main() int arrayN; for (int i=0; i cinarrayi; print(array, N); void print(const int *p, int n) cout<<<<*p; for (int i=1; i cout<<,<<*(p+i); cout<<< ,常成員函數(shù) 使用const關鍵字進行說明的成員函數(shù),稱為常成員函數(shù)。只有常成員函數(shù)才有資格操作常量或常對象,沒有使用const關鍵字說明的成員函數(shù)
13、不能用來操作常對象。常成員函數(shù)說明格式如下: () const; 其中,const是加在函數(shù)說明后面的類型修飾符,它是函數(shù)類型的一個組成部分,因此,在函數(shù)實現(xiàn)部分也要帶const關鍵字。下面舉一例子說明常成員函數(shù)的特征。,#include class R public: R(int r1, int r2) R1=r1; R2=r2; void print(); void print() const; private: int R1, R2; ;,void R::print() cout< void R::print() const cout< void main() R a(5, 4); a.
14、print(); const R b(20, 52); b.print(); 該例子的輸出結果為: 5,4 20;52,,2Inline 內聯(lián)函數(shù) 包含在類的說明中的成員函數(shù)稱為內部函數(shù) 它告訴編譯器一旦有可能就直接用該函數(shù)的代碼取代對該函數(shù)的調用,以避免函數(shù)調用的開銷,class 類名 成員變量; 成員函數(shù); 即使不是在類說明中定義的函數(shù),也可以說明為內部的(加inline) 以空間換時間,內聯(lián)函數(shù)的限制 (1)內聯(lián)函數(shù)不能包含任意靜態(tài)數(shù)據 (2)內聯(lián)函數(shù)不能使用任何循環(huán) switch,goto語句 (3)內聯(lián)函數(shù)不能是遞歸的 (4)內聯(lián)函數(shù)中不能有數(shù)組說
15、明(可 放在外面說明),幾個重要概念 1函數(shù)原型 int get_ word ( char *, int , float ); 把函數(shù)的函數(shù)名,返回類型及使用的參數(shù)的類型和個數(shù)提前告訴編譯程序 1)函數(shù)原型通常放在程序的頂部 2)c++需要所有函數(shù)都有原型,2缺省參數(shù) int g( char a, int b, int c=0 ); 調用時若未給第三個參數(shù),則缺省為0 (1)所有取缺省值的參數(shù)都必須出現(xiàn)在不取缺省值的參數(shù)的右邊 (2)缺省值只需在第一次被提及的地方指定,3引用類型 數(shù)據的一種類型(同指針類型很相似) c只能通過傳值傳遞參數(shù),不能通過傳遞引用傳遞參數(shù) c++不僅通過傳值傳
16、遞參數(shù),也可通過傳遞引用傳遞參數(shù),(1)引用的概念 引用是給對象(變量)取一個別名,它引入了對象的一個reference 在C中只能使用指針建立別名,不能使用引用建立別名 在C++中不僅使用指針建立別名,也可使用引用建立別名,定義引用的關鍵字是type int 創(chuàng)建了一個整型引用變量j,它是i的地址的別名,即j是i的同義詞,它們表示同一個對象,例二 int i; int // 正確,不必給出初值,例三 int i; int i,j的值均為6 引用是對象本身,而不是副本,所以對對象或對引用的任何操作都會影響到它們共同的對象,一個引用可看作一個特殊類型的指針 引用與指
17、針的差別 (1)引用必須初始化 (2)初始化后不能再作為其他對象 的別名,引用可以使用臨時變量來進行初始化 (1)用常量初始化引用(引用為常量的別名) int (T1為臨時變量),(2)用不同類型的對象初始化引用 unsigned int ui=20; int (T2為臨時變量),(2)引用的用途 獨立引用 作為函數(shù)參數(shù)類型 作為函數(shù)返回類型,1)獨立引用 a.獨立引用的限制 b.理解 int * main () 中調用語句 int x, i=4; void a2( int *n ) x=a1(i); //x=12, i=4
18、*n=(*n)*3; a2 ( ,,傳值的缺點 1、單向傳遞,結果無法返回 2、對于大型對象,實參對形參的 賦值耗時太多,3)作為函數(shù)返回類型 甚至可使返回值作為賦值號左側的元素,即函數(shù)調用可以放在賦值語句的左端,類的一般形式 class 類名 private: 私有段數(shù)據及函數(shù); protected: 保護段數(shù)據及函數(shù); public: 公有段數(shù)據及函數(shù); ;,成員變量和成員函數(shù) 1成員變量 成員變量的聲明與普通變量的聲明方式相同,但聲明中不允許進行初始化賦值,允許 不允許 class stack class stack int *lst;
19、 int*lst; int max_size; int max_size; int nb_elements; int nb_elements=0; ; ; 一般在聲明時,應按成員變量類型的大小,從小至大聲明,這樣利于機器進行對準操作,從而提高時空利用率,(3)在類的內部,可以定義其自身的 引用或者指針 class stack int *lst; int max_size; int nb_elements; ;,class stacklinker stack mystack; stacklinker *right, *left; ;,2成員函數(shù) 棧的六種操
20、作建棧、判棧、入棧、出棧、讀棧、毀棧在類中應給出成員函數(shù)的原型,class stack public: void create( int ); int empty( ); void push( int ); void pop( ); int top( ); void erase( ); ;,成員函數(shù)的具體實現(xiàn)可在類定義體內(為內聯(lián)函數(shù)),也可在類定義體外(加上inline成為內聯(lián)函數(shù),不加inline成為一般函數(shù)) stack 的完整實現(xiàn)如下:,#include #include const char *msg = ”stack is empty!n”, ”
21、stack is overflow!n” ; class stack int *lst; int nb_elements; int max_size; void err_msg( int );,public: void create( int ); int empty( ); void push( int ); void pop( ); int top( ); void erase( ); ; viod stack::err_msg( int code ) cout< 22、ze; lst=new int(size); nb_elements=0; int stack::empty( ) return (nb_elements==0); ,void stack::push( int element ) if ( nb_elements==max_size ) err_msg (1); else lst++nb_elements=element; ,void stack::pop( ) if ( nb_elements==0 ) err_msg(0); else --nb_elements; ,int stack::top( ) if ( nb_e 23、lements==0 ) err_msg(0); else return(lstnb_elements); void stack::erase( ) delete lst; ,main( ) stack s; int i; s.create(100); for( i=0; i<=100; ++i )s.push(i); for( i=0; i<=100; ++i ) cout< 24、is empty,類類型常量和const成員函數(shù) 1 13 5 為 int 型常量 2.3 5.7 為double型常量 C f 為 char 型常量 某些類類型存在常量 如:有復數(shù)類complex, 則2+3i為complex類的類型常量 不存在像基本類型常量那樣形式的類類型 常量,類類型的常量是以其他方式表達的,2 在程序中對const聲明的常量進行賦值是不允許的 const char blank= ; blank=0; error,3只有通過公有成員函數(shù)才能修改一個類的對象 為了確保某個對象是常量,編譯器必須有辦法 區(qū)別“安 全”及“不安全”的成員函數(shù) const 25、stack s; cout< 26、/聲明 .. int stack::top( )const //定義 ; ;,若某個函數(shù)修改了類中的某個成員變量, 則不允許把它聲明為const型的 class example int *data_member; public: void ok( int i )const//允許 *data-member=i; void err( int *i )const//不允許 data-member=i; ; const成員函數(shù)也可以重載,構造函數(shù)的功能:初始化對象 析構函數(shù)的功能:釋 放 空 間 1.構 27、造函數(shù): 系統(tǒng)缺省版本:做公共初始化工作 用戶提供版本:做用戶初始化工作 2.析構函數(shù): 系統(tǒng)缺省版本:做公共的善后工作 用戶提供版本:做用戶的善后工作 構造函數(shù)和析構函數(shù)都具有普通成員函數(shù) 的許多共同特性,但也有獨特的特性,1.共同點 (1)沒有返回類型 (2)不能被繼承 (3)不能取它們的地址 2.不同點 (1)構造函數(shù)可以有參數(shù) 析構函數(shù)不能有參數(shù) (2)構造函數(shù)不能是虛函數(shù) 析構函數(shù)可以是虛函數(shù) (3)構造函數(shù)不能顯式調用 析構函數(shù)可以顯式調用 當定義對象時系統(tǒng)自動調用構造函數(shù)(先系后用) 當刪除對象時系統(tǒng)自動調用析構函數(shù)(先 28、用后系),(1)構造函數(shù)的名字必須與類名相同 (2)構造函數(shù)沒有返回值,在聲明和定義 構造 函數(shù)時是不能說明類型的 (3)構造函數(shù)只能對數(shù)據成員做初始化, 這些數(shù)據成員一般為私有成員 (4)構造函數(shù)一般不做賦初值以外的事情 (5)構造函數(shù)不能顯式地調用,析構函數(shù) 類的一個特殊成員函數(shù),函數(shù)名與類名相同, 只是在前面加上一個“” class string string::string( ) int length; delete contents; char *contents; public; string( char * ); string( ) 29、; ;,(1)一般析構函數(shù)由一系列的delete語句 組成 (2)若使用完全限定名,可顯式調用析構 函數(shù),參數(shù)化的構造函數(shù) class point int x, y; public: point( int, int ); void offset( int , int ); ; point::point( int vx, int vy ) x=vx; y=vy; void point::offset( int ax, int ay ) x=x+ax; y=y+ay; main( ) point pt(10,20); pt.o 30、ffset (10,10); ,缺省參數(shù)的構造函數(shù) 例一. class set int elems100; int size; int card; public: set( int i=16 ); ; set::set( int i ) size=i; if (size100) size=100; if ( size<16 ) size=16; main( ) set s1(64), s2(16), s3(8), s4; s 31、ize取值 64 16 16 16,例二. class point int x, y; public: point ( int vx=0; int vy=0 ) x=vx; y=vy; ; main( ) point p1; //不傳遞參數(shù) x= 0, y= 0 point p2(10); //只傳遞一個參數(shù) x=10, y= 0 point p3(10,20); //傳遞兩個參數(shù) x=10, y=20 ,重載構造函數(shù) class x public: x( ); x( int ); x( int, char ); x( float, char ); ; void f( 32、) x a, b(1), c(1, c), d(2.3, d); ,注意二義性 class x public: x( ); x( int i=0 ); ; main ( ) x a(10); //正確 x b; //錯誤 ,,拷貝構造函數(shù) 一種特殊的構造函數(shù) (1)為一個構造函數(shù),當創(chuàng)建一個新對象時 系統(tǒng)自動調用它 (2)它將參數(shù)代表的對象逐域拷貝到新創(chuàng)建 的對象中 拷貝構造函數(shù)是將自己所在的類的引用作 為構造函數(shù)的參數(shù) 拷貝構造函數(shù)的定義的兩種形式 1.系統(tǒng)產生 2.用戶定義,1系統(tǒng)產生 # include class point int x, y; public: 33、 point( int vx, int vy ) x=vx; y=vy; void print( ) cout< 34、ain( ) main( ) point p1(10,20); point p1(10,20); point p2(p1); point p2=p1; ,第 三 節(jié) this指針,C++為成員函數(shù)提供了一個稱為this的 指針,this在所有成員函數(shù)調用里作為一個 隱含參數(shù)傳給成員函數(shù) class point int x, y; public: point( int vx, int vy , point *const this ) //完整 this-x=vx; this-y=vy; point( int vx, int vy ) 35、 //半省 this-x=vx; this-y=vy; point( int vx, int vy ) x=vx; y=vy; //全省 ;,1每個對象的成員函數(shù)都擁有一個隱含的指 針this(靜態(tài)函數(shù)除外) int get_length( ) return length; 二者等價 int get_length( ) return this-length; 2this指針是一個常指針,可表示為: x *const this (可指向常量) 3this指針不能被修改和賦值 4const成員函數(shù)不能修改this所指的對象的 成員,第 四 節(jié) 36、 靜態(tài)成員,一、靜態(tài)成員變量 (1)某個類的所有對象要共同訪問同一個變 元,這個變元可能是一個條件標志或一 個計數(shù)器 (2)為了減少數(shù)據冗余,防止不一致性,要 求一個類的所有對象共享同一個數(shù)據 (3)為了節(jié)約空間開銷,也要求對象共享同 一個數(shù)據 處理方法:使用全局變量 缺點:(1)破壞了信息隱藏原則 (2)過多的全局變量會產生重名沖突,為了既達到與全局變量一樣的效果,又能 滿足信息隱藏的原則,提出了靜態(tài)成員變量的 概念 特 點 若類中某個成員變量被說明成靜態(tài)的,則 類的所有對象共享這個成員變量 靜態(tài)成員變量不屬于某個對象,而屬于整個類,class ABCD 37、char ch; static int s; ; ABCD a, b, c, d; 為了把某個成員變量說明為靜態(tài)的,只須 在原有說明前加上static 靜態(tài)成員變量可以是public、private和 protected段的,#include #include class counter static int count; int objnumber; public: counter () count++; obinumber=count; void show() cout<<”obj”< 38、<”n”; ; int counter::count=0;,main() counter obj1,obj2,obj3,obj4; obj1.show(); cout<<”--------------------n”; obj1.show(); obj2.show(); cout<<”--------------------n”; obj1.show(); obj2.show(); obj3.show(); cout<<”--------------------n”; obj1.show(); obj2.show(); obj3.show(); obj4.show(); ,輸出結果: ob 39、j1count=4 ---------------- obj1count=4 obj2count=4 ---------------- obj1count=4 obj2count=4 obj3count=4 ---------------- obj1count=4 obj2count=4 obj3count=4 obj4count=4,靜態(tài)成員函數(shù) static函數(shù) 1是一個成員函數(shù),使用時要用“類名::” 作為它的限定詞 2是一個特殊的成員函數(shù),它不屬于某一 個特定的對象而只屬于一個類,不能象 一般的成員函數(shù)那樣隨意地訪問對象中 的非靜態(tài)的數(shù)據內容 3沒有this指針 4要訪問非靜態(tài)成員, 40、必須要有限定詞,#include #include class string static int total_length; int length; char *contents; public: string(char ,main() string obj1(“The first object”); cout< 41、tic int set_total_length(string obj) total_length=total_length+obj.length; return total_length; main() string obj1(“The first object”); cout< 42、和信息隱藏使對象和外界以 一堵不透明的墻隔開,友元在這堵 墻上開了一個小孔 (2)友元是以犧牲信息隱藏原則,削弱 封裝性來提高編程效率,增大了類 與類之間的藕合度 只要將外界的某個對象說明為某一個類 的友元,則它可以訪問這個類中的所有成員 友元的種類 1.一般函數(shù) 2.另一個類的成員函數(shù) 3.另一個類,二、友元的聲明和定義 將friend放在函數(shù)名或類名的前面,此 聲明可放在任何段中 特別注意 友元不屬于任何類,三、友元函數(shù) 作為友元的函數(shù) class x int i; friend void func(x *, int); //友元函數(shù) pu 43、blic: void member_func(int); //成員函數(shù) ; void func(x *xp, int a)xpi=a; //無需作用域 void x::member_func(int a)i=a; //必須作用域,成員函數(shù)可以在類中實現(xiàn),也可以類外實現(xiàn) 友元函數(shù)可以在類中實現(xiàn),也可以類外實現(xiàn) 在類外實現(xiàn)時,成員函數(shù)必須用作用域 區(qū)分符(::)限定它屬于哪一個類 在類外實現(xiàn)時,友元函數(shù)不須用作用域 區(qū)分符(::)限定它屬于哪一個類 友元函數(shù)沒有this指針,不能確定是訪問 哪個對象的私有數(shù)據,故必須在參數(shù)表中顯 式地指明要訪問的對象,友元成員函數(shù) 作為友元的 44、另一個類中的成員函數(shù) class x public: void member_func(); ; class y int i ; friend void x::member_func(); ;,友元類 作為友元的另一個類 class x int i, j; public: void member_func1(); void member_func2(); void member_func3(); ; class y int i, j; friend x; ;,運 算 符 重 載,不能改變優(yōu)先級 不能改變操作數(shù)的個數(shù) 不能重載沒有的符號(自 45、己發(fā)明) 單目可以重載 雙目可以重載 三目不能重載 運算符重載的能力增強了C++語言的可擴充性 new可以重載 delete可以重載,在C++中,運算符的重載,實際上是 一種函數(shù)調用的形式 用成員函數(shù)重載運算符 用友元函數(shù)重載運算符 +可以定義為減運算 *可以定義為除運算 顛倒黑白,重載方式的選擇 (1)若運算符的操作要修改對象的狀態(tài), 或需要左值運算數(shù)(如=,*=,++),選擇 成員函數(shù) (2)若運算符的操作數(shù)(特別是第一個操 作數(shù))希望有隱藏類型轉換,必須選擇友元 函數(shù) 既要聲明、也要定義,用成員函數(shù)重載運算符 重載運算符的成員函數(shù)稱為運算符重載函數(shù), 有this指針,是 46、一種特殊的成員函數(shù) 1.聲明格式 class class_name type operator(arg-list); 2.定義格式 type class_name::operator(arg-list) 其中:type為返回類型,為要重載的運算符 operator為關鍵字,arg-list為該運算所需要的操作數(shù) 若為一元的,則arg-list為空,當前對象作為單操作數(shù) 若為二元的,則arg-list中有一個操作數(shù),當前對象為 的左操作數(shù),arg-list中的操作數(shù)為的右操作數(shù),隱式調用 顯式調用 一元 aa或aa aa.operator() 無參數(shù),隱式傳遞 隱式調 47、用 顯式調用 二元 aabb aa.operator(bb) 一個參數(shù),一隱一顯,例1 class x int operator+( x ); ; int x::operator+( x a ) main() x a1,b1; y a2,b2; a1=a1+b1; //正確 a2=a2+b2; //錯誤 類x對+已進行重載 類y對+未進行重載,例2 class point int x,y; public: point(int vx, int vy)x=vx; y=vy; point()x=0; y=0; point operator+( point p); p 48、oint operator -( point p); void print()cout< 49、符 重載運算符的友元函數(shù)也稱為運算符 重載函數(shù) 1.聲明格式 class class_name friend type operator(arg-list); 2.定義格式 type operator(arg-list) 若為一元的,則arg-list中有一個操作數(shù), 作為唯一的操作數(shù) 若為二元的,則arg-list中有二個操作數(shù), 作為運算的兩個操作數(shù),,,隱式調用 顯式調用 一元 aa或aa operator(aa) 一個參數(shù),顯式傳遞 隱式調用 顯式調用 二元 aabb operator(aa, bb) 二個參數(shù),顯式傳遞, 50、例1 class point int x,y; public: point(int vx, int vy)x=vx; y=vy; point()x=0; y=0; friond point operator+(point p1; point p2); friond point operator -(point p1; point p2); void point()cout< 51、 operator-(point p1; point p2); point p; p.x=p1.x-p2.x; p.y=p1.y-p2.y; return p; main() point p1(10,10); p2(20,20); p1=p1+p2; p1.print(); 運算結果:30 30,注 意 1.為什么要用友元函數(shù)重載運算符 2.=,(),,只能用成員函數(shù)重載 3.只能用友元函數(shù)重載 4.友元函數(shù)重載單目運算符時要特別小心 若單目運算符要改變對象的狀態(tài),且用 友元函數(shù)重載該運算符,則應使用引用 參數(shù),三、幾個特殊運算符的重載 1++和-- 前綴方式 ++i, --i 52、 后綴方式 i++, i-- (1)前綴方式 aa.operator++() 成員函數(shù)重載 operator++(X //ok,= 賦值運算符 不能被友元函數(shù)重載,不能被繼承 自動重載:系統(tǒng)定義 人工重載:用戶定義 缺省拷貝構造函數(shù):新建一個對象,再拷貝 缺省賦值運算符重載函數(shù):只拷貝(目的對象已存在) 例 A a; A b=a;(調用缺省拷貝構造函數(shù)) A a,b; b=a;(調用缺省賦值運算符重載載函數(shù)) 缺省的成員函數(shù)重載賦值運算符 X int length; string 現(xiàn)在可以使用:str1=str2,例2 指針懸掛問題 class 53、string 僅有缺省賦值運算符有時是不夠的 char *contents; int size; public: string(int sz)contents=new charsz; string()delete contents; ; 沒有重載賦值運算符 main() string s1(10), s2(20); s1=s2; // 調用缺省賦值運算符 缺省賦值運算符的功能:逐域賦值 (1)s2的contents-s1的contents (2)s2的size-s1的size,解決方法:重載賦值運算符 使其不僅能賦值成員contents,size, 也要復制非成員(具體內 54、容) 加上:void operator=(string *); void string::operator=(string *str) if(this==str)return; delete contents; contents=new charsize=strsize; strcpy(contents, strcontents); 解決了指針懸掛問題,3( )和 函數(shù)調用運算符和下標運算符 例1 class string char *ptr; public: string(const char *); char ssS的新值為”afdf”,new和delete的重載,(1) 55、new和delete是運算符,可以重載 (2)申請空間可以是基本內存,擴充內 存、擴展內存、硬盤 重載類型 局部重載:在某一個類中進行,用成員函數(shù) 重載運算符函數(shù) 全局重載:在任何類外進行,用普通函數(shù)重 載運算符函數(shù) new 可重載 malloc() 不可重載 delete free(),void *operator new(size-t size, ) // 完成分配工作 return pointer-to-memory; void operator delete(void *p, ) // 釋放由P指向的存貯空間 (1)對operator new()來說, 56、它的第一個參數(shù)必須 是size-t類型,這是一個在標準頭文件 中定義的與實現(xiàn)有關的整型類型, 必須返回void *類型 (2)對operator delete來說,它的第一個參數(shù)必須 是void *類型,第二個參數(shù)的類型是size-t (可選,刪除對象的大小),必須返回void類型,局部重載 (1)類x的x::operator new() 類x的x::operator delete() 它們不是針對x類的對象操作的是靜態(tài)成員 函 數(shù)(無論是否有static) (2)new在構造函數(shù)之前調用,分配構造函數(shù)建 立X類對象的內存 delete在析構函數(shù)之后調用,釋放析構 57、函數(shù) 剛剛破壞的X類對象的內存 (3)一個類只能聲明一個operator delete(),故 operator delete()不能進行函數(shù)重載 一個類可以聲明多個operator new(),故 operator new()可以進行函數(shù)重載 (4)重載的new()和delete()是可以繼承的,類 型 轉 換,一般類型轉換 隱式類型轉換(標準類型轉換) 顯式類型轉換 強制轉換法 函數(shù)轉換法 強制法 函數(shù)法 int i, j; int i, j; cout<<(float)(i+j); cout<<(float(i 58、+j) 類類型轉換 構造函數(shù) 轉換函數(shù),標準類型標準類型:標準類型轉換 標準類型類 類 型:構 造 函 數(shù) 類 類 型標準類型:類型轉換函數(shù) 類 類 型類 類 型:類型轉換函數(shù),一、構造函數(shù) 不能將類類型轉換為類類型 只能將標準類型轉換為類類型 不能將類類型轉換為標準類型 條件:此類一定要有一個只帶一個參數(shù)的 構造函數(shù),二、轉換函數(shù) 特殊的成員函數(shù)(不能為友元函數(shù)), 可以被繼承、可以是虛函數(shù)、不能重載 (函數(shù)重載),無參數(shù),無返回類型,必 須有返回函數(shù),返回具有type類型的對象。 X::operator Y() 59、Y y; return y; 功能:X 類類型標準類型 X類類型Y類類型,隱式使用:int i=a; 顯式使用:int i=a.operator int(); 一般使用隱式方式,僅當需要 明確指出所使用的是哪一個轉換 函數(shù)時才使用顯式方式,二義性問題 若X類有 X(int) 構造函數(shù) operator int() 轉換函數(shù) 則 int i=a; 隱式調用轉換函數(shù) X a=i; 隱式調用構造函數(shù) 則語句 a=a+i 將會產生二義性, 此時必須顯式調用轉換函數(shù) 用戶定義的轉換函數(shù)只有 在無二義性時才能隱式使用,解決方法 (1) X b=i; (2) a=a+X(i 60、); a=a+b; 說明: (1) 編譯程序先按用戶定義的意思, 再按標準格式,都不行,則失敗 (2) 有二義性時,必須使用顯式類型 轉換 (type)obi 或 type(obi),派 生 類,提高軟件的可重用性 減少工作量 避免編寫重復代碼 減少出錯機會 繼承是對象類間的一種相關關系, 即派生關系,并具有以下性質: 類間的共享特性 類間的細微區(qū)別 類間的層次結構 分類樹反映了派生關系: 最高層是最普遍最一般的,越往下 反映的事物越具體,并且下層都包含了 上層的特征,派生類的概念,引入繼承的目的在于為代碼重用提 供有效手段。一方面使用繼承可以重用 先前項 61、目的代碼,若原來的代碼不能完 全滿足要求,還可以作少量的修改,滿 足不斷變化的具體應用要求,從而提高 程序設計的靈活性,避免不必要的重復 設計,單 繼 承,單繼承:每個類可有多個派生類, 但最多只有一個基類, 從而形成一棵樹結構 多繼承:每個類可有多個派生類, 也可有多個基類,從而 形成網狀結構,一、定義格式: class 派生類名:繼承方式 基類名 ; 其中:1.class 關鍵字 2. : 將派生類與基類分開 3.繼承方式: public protected private 缺省: 對于類等價于private 對于結構等價于pub 62、lic,四種繼承方式 1公有派生 class 派生類名:public 基類名 ; 基類所有公有段成員成為派生類公有段成員 基類所有保護段成員成為派生類保護段成員 基類所有私有段成員不能被繼承 即派生類的對象及其成員函數(shù)可直 接訪問基類的公有成員和保護成員,2私有派生 class 派生類名:private 基類名 ; 基類所有公有段成員成為派生類私有段成員 基類所有保護段成員成為派生類私有段成員 基類所有私有段成員不能被繼承 即派生類的成員函數(shù)可直接訪問 基類的公有成員和保護成員,3保護派生: class 派生類名:protected 基類名 ; 基類所有公有段成員成為派生類保護段成員 63、基類所有保護段成員成為派生類保護段成員 基類所有私有段成員不能被繼承 即派生類的成員函數(shù)可直接訪問基類 的公有成員和保護成員,還可往下繼承,4部分公開(訪問聲明): 為了使基類中的公有和保護 成員在派生類中部分成為公有或 保護成員,部分成為私有成員, 可采用: 基類名::成員名 基類公有成員等價于派生類公有成員 基類保護成員等價于派生類保護成員 注意 (1)并未引進新成員 (2)在調整名字的訪問時 不能說明 類型,三、成員訪問控制 基類性質 繼承性質 派生類性質 public public public protected public pr 64、otected private public 不能訪問 public protected protected protected protected protected private protected 不能訪問 public private private protected private private private private 不能訪問,基類與派生類的關系 任何一個類都可以派生出一個新類,派生類也可以再派生出新類,因此,基類和派生類是相對而言的。一個基類可以是另一個基類的派生類,這樣便形成了復雜的繼承結構 65、,出現(xiàn)了類的層次。一個基類派生出一個派生類,它又做另一個派生類的基類,則原來的基類為該派生類的間接基類。 1. 派生類是基類的具體化。 2. 派生類是基類定義的延續(xù)。 3. 派生類是基類的組合。 派生類將其本身與基類區(qū)別開來的方法是添加數(shù)據成員和成員函數(shù)。因此,繼承的機制將使得在創(chuàng)建新類時,只需說明新類與已有類的區(qū)別,從而大量原有的程序代碼都可以復用。,,如:class A public: void f(); ; class B public: void f(); void g(); ; class C: public A,public B public: voi 66、d g(); void h(); ; C obj;,則對函數(shù)f()的訪問是二義的:obj.f(); //無法確定訪問A中或是B中的f(),,賦值兼容規(guī)則 賦值兼容規(guī)則是指:在公有派生的情況下,一個派生類的對象可用于基類對象適用的地方。賦值兼容規(guī)則有三種情況(假定類derived由類base派生) : (1)派生類的對象可以賦值給基類的對象。 derived d; base b; b=d; (2)派生類的對象可以初始化基類的引用。 derived d; base,,(3)派生類的對象的地址可以賦給指向基類的指針。 derived d; base *pb=,,,,,多態(tài)性是面向對象程序設計的重要特征之一。所謂多態(tài)性是指當不同的對象收到相同的消息時,產生不同的動作。C++的多態(tài)性具體體現(xiàn)在運行和編譯兩個方面,在程序運行時的多態(tài)性通過繼承和虛函數(shù)來體現(xiàn),而在程序編譯時多態(tài)性體現(xiàn)在函數(shù)和運算符的重載上。,運算符重載的實現(xiàn),運算符的重載形式有兩種:重載為類的成員函數(shù)和重載為類的友元函數(shù)。 運算符重載為類的成員函數(shù)的語法形式如下: operator () ; friend operator
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
5. 裝配圖網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。