C++面向?qū)ο蟪绦蛟O(shè)計(jì)課件第3章_第1頁
C++面向?qū)ο蟪绦蛟O(shè)計(jì)課件第3章_第2頁
C++面向?qū)ο蟪绦蛟O(shè)計(jì)課件第3章_第3頁
C++面向?qū)ο蟪绦蛟O(shè)計(jì)課件第3章_第4頁
C++面向?qū)ο蟪绦蛟O(shè)計(jì)課件第3章_第5頁
已閱讀5頁,還剩73頁未讀 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

本章導(dǎo)讀C++語言是當(dāng)今應(yīng)用最廣泛的程序設(shè)計(jì)語言,它與C語言兼容,既支持面向?qū)ο蟮某绦蛟O(shè)計(jì),也支持面向?qū)ο蟮某绦蛟O(shè)計(jì)方法。C語言中編寫的程序是由一個(gè)個(gè)函數(shù)組成的,是結(jié)構(gòu)化的程序,而C++除了兼容結(jié)構(gòu)化程序設(shè)計(jì)之外,還可以編寫面向?qū)ο蟮某绦?。在第一章中,我們已?jīng)初步了解了類和對象的概念,從本章開始,我們將編寫由類和對象組成的程序,也就是說,將要學(xué)習(xí)用C++語言進(jìn)行面向?qū)ο蟮某绦蛟O(shè)計(jì)。類和對象是面向?qū)ο蟪绦蛟O(shè)計(jì)語言中的最基礎(chǔ)內(nèi)容。類是封裝數(shù)據(jù)和函數(shù)的基本單元。是用戶根據(jù)實(shí)際問題自己抽象的一種類型。對象是用類名作為一種數(shù)據(jù)類型定義的“變量”,稱為類的實(shí)例。類和對象具有抽象性、隱蔽性和繼承性。本章要點(diǎn)類與對象的概念和定義、類成員的訪問權(quán)限構(gòu)造函數(shù)(包括復(fù)制構(gòu)造函數(shù))和析構(gòu)函數(shù)的概念和用法this指針的用法類作用域的概念靜態(tài)數(shù)據(jù)成員和靜態(tài)成員函數(shù)的概念和用法友元概念和用法第三章目錄3.1類的概念 3.2對象 3.3構(gòu)造函數(shù) 3.4析構(gòu)函數(shù) 3.5再談構(gòu)造函數(shù) 3.6程序舉例 3.7本章小結(jié)

習(xí)題三 3.1類的概念 3.1.1類的引入3.1.2類的定義3.1.3類的成員函數(shù)3.1.1類的引入在C語言中,我們學(xué)習(xí)使用過結(jié)構(gòu),結(jié)構(gòu)是一種自定義的數(shù)據(jù)類型,它將有關(guān)聯(lián)的不同類型的數(shù)據(jù)元素組成一個(gè)單獨(dú)的統(tǒng)一體。例如定義一個(gè)點(diǎn)(x,y)的結(jié)構(gòu):structPoint{intx;inty;};在結(jié)構(gòu)Point中包含了2個(gè)數(shù)據(jù)元素,即橫坐標(biāo)x和縱坐標(biāo)y。在結(jié)構(gòu)中可以對各數(shù)據(jù)元素進(jìn)行各種操作。在C語言中,當(dāng)我們建立了一個(gè)結(jié)構(gòu)變量,就可以在結(jié)構(gòu)體的外直接對其數(shù)據(jù)變量進(jìn)行修改,原因是結(jié)構(gòu)的成員在默認(rèn)的情況下為公有的。而有些時(shí)候我們并不允許對數(shù)據(jù)進(jìn)行改動。但在C結(jié)構(gòu)中,數(shù)據(jù)與對數(shù)據(jù)的操作是分離的,它沒有把相關(guān)的數(shù)據(jù)與操作夠成一個(gè)整體進(jìn)行封裝,正是由于這種原因,造成了C結(jié)構(gòu)中數(shù)據(jù)的不安全性,C結(jié)構(gòu)中無法對數(shù)據(jù)進(jìn)行保護(hù)和權(quán)限控制。因此使得程序的復(fù)雜性加大,對數(shù)據(jù)的維護(hù)和處理都需要很大的精力,嚴(yán)重影響了軟件的生產(chǎn)效率。C++引入了類,它克服了C結(jié)構(gòu)的缺點(diǎn),使數(shù)據(jù)和其相關(guān)聯(lián)的函數(shù)封裝在一起,構(gòu)成一個(gè)統(tǒng)一的整體,很好的實(shí)現(xiàn)了數(shù)據(jù)保護(hù)和權(quán)限控制。3.1.2類的定義類的構(gòu)成一般分為說明部分和實(shí)現(xiàn)部分。說明部分放在類體內(nèi),用來說明該類中的數(shù)據(jù)成員和成員函數(shù)的類型和名稱,是類的外部接口。實(shí)現(xiàn)部分常放在類體外,用以給出說明部分中聲明的成員函數(shù)的定義,是類的內(nèi)部實(shí)現(xiàn)。類定義的說明部分的一般格式如下:class

類名{private:私有數(shù)據(jù)成員和成員函數(shù)Protected:保護(hù)數(shù)據(jù)成員和成員函數(shù)Public:公有數(shù)據(jù)成員和成員函數(shù)};其中,class關(guān)鍵字表明進(jìn)行一個(gè)類的定義,class之后是類的名稱,一般首字符要大寫,以區(qū)別于對象名。類體被一對花括號“{

}”括起,同結(jié)構(gòu)體一樣,最后以分號結(jié)束。在類內(nèi)只對成員函數(shù)進(jìn)行原型說明,函數(shù)體的定義常寫在類外。例如定義一個(gè)日期類如下:classstudent{private: charname; intnumber; chargrade;public: voidsetStudent(intna,intnu,intgr); voidshowStudent();};在聲明的類student中,封裝了有關(guān)數(shù)據(jù)和對這些數(shù)據(jù)的操作,分別稱為類student的數(shù)據(jù)成員和成員函數(shù)。在類student中,因?yàn)閿?shù)據(jù)成員和成員函數(shù)有著不同的訪問權(quán)限,所以分別屬于private和public兩個(gè)不同部分。類具有對數(shù)據(jù)的隱蔽性,在類體部分,有關(guān)鍵字private、protected和public三個(gè)訪問權(quán)限控制符,每個(gè)關(guān)鍵字下面都可以有數(shù)據(jù)成員和成員函數(shù)。數(shù)據(jù)成員和成員函數(shù)統(tǒng)稱為類的成員。private表示類的私有成員,包括私有數(shù)據(jù)成員和私有成員函數(shù)。私有成員只有類自己的成員函數(shù)或友元函數(shù)可以訪問,在類的外部訪問都是不允許的,如果類外的函數(shù)要訪問私有成員,必須通過類的公有成員函數(shù)來訪問。私有成員隱蔽在類中,在類的外部無法訪問,實(shí)現(xiàn)了訪問權(quán)限的有效控制。protected表示類的保護(hù)成員,包括保護(hù)數(shù)據(jù)成員和保護(hù)成員函數(shù)。保護(hù)成員除了類自己的成員函數(shù)、友元函數(shù)可以訪問外,派生類的成員也可以訪問,即它是半隱蔽的。public表示類的公有成員,包括公有數(shù)據(jù)成員和公有成員函數(shù)。說明其內(nèi)容可以被自由訪問。既可以被該類的其他成員函數(shù)訪問,也可以被類外的其他函數(shù)訪問。即它是完全開放的。關(guān)于類的定義,應(yīng)該注意以下幾個(gè)問題:(1)在一個(gè)類中,聲明類的三個(gè)部分并不一定全部出現(xiàn),但至少要有其中的一部分。一般情況下,為了數(shù)據(jù)得到有效的保護(hù),將類的數(shù)據(jù)成員聲明為私有成員,成員函數(shù)聲明為公有成員。(2)類的聲明中private、protected和public可以按任意順序出現(xiàn),如果私有部分處于類體的第一部分時(shí),關(guān)鍵字private可以省略,否則不能省略。如果在類體中沒有一個(gè)訪問權(quán)限關(guān)鍵字,則類的成員默認(rèn)為私有的。而關(guān)鍵字private和protected無論出現(xiàn)在何處都不可以省略。(3)數(shù)據(jù)成員可以是任何數(shù)據(jù)類型,但不能用自動(auto)、寄存器(register)或是外部(extern)進(jìn)行說明。(4)由于不同的類中的成員的作用域不同,所以不同的類的成員可以同名。(5)不能在類的聲明中給數(shù)據(jù)成員賦初值。只有在類的對象定義之后才可以對數(shù)據(jù)成員賦初值。3.1.3類的成員函數(shù)成員函數(shù)的一般格式如下:返回類型

[類名::]成員函數(shù)名(參數(shù)表){

…//函數(shù)體}其中,可選項(xiàng)[類名::]的有無與下列兩種方式有關(guān)。1.在類聲明中只給出成員函數(shù)的原型,而其定義在類的外部,這時(shí)在類外定義的成員函數(shù)一定要加上[類名::]選項(xiàng)。::為作用域運(yùn)算符,指明該成員函數(shù)屬于哪個(gè)類。在類體外定義成員函數(shù)時(shí),必須使用作用域運(yùn)算符。在類內(nèi)定義成員函數(shù)時(shí),可以直接使用成員函數(shù)的名字。關(guān)于在類外定義的成員函數(shù),要注意如下幾個(gè)問題:(1)在類外定義成員函數(shù)時(shí),調(diào)用成員函數(shù)時(shí)必須在函數(shù)名前加類名::。(2)成員函數(shù)如果有參數(shù),則其參數(shù)說明必須是完整的。(3)成員函數(shù)的返回類型應(yīng)與函數(shù)原型聲明相同。2.將成員函數(shù)定義為內(nèi)聯(lián)函數(shù)的形式,可有以下兩種方式實(shí)現(xiàn):(1)隱式定義直接將函數(shù)定義在類的內(nèi)部,[類名::]選項(xiàng)可以省略。如:classPoint{private: intx,y;public: voidsetPoint(inta,intb) {x=a;y=b;} intgetx() {returnx;} intgety() {returny;}};這樣,函數(shù)setPoint()、getx()和gety()就被定義為隱含的內(nèi)聯(lián)函數(shù)。(2)顯示定義在類中只給出成員函數(shù)的原型,其定義在類的外部,但如果想讓其起到內(nèi)聯(lián)函數(shù)的作用,可以在成員函數(shù)返回類型前加上關(guān)鍵字“inline”,可選項(xiàng)[類名::]不能省略。一般形式為:inline返回類型類名::成員函數(shù)名(參數(shù)表){…//函數(shù)體}類中的數(shù)據(jù)成員的類型可以是任意的,包括整型、浮點(diǎn)型、數(shù)組、指針、引用和別的類的對象,但類定義不允許對數(shù)據(jù)成員進(jìn)行初始化。3.2對象3.2.1對象的定義3.2.2對象成員的訪問3.2.3類成員的訪問屬性3.2.4對象賦值語句3.2.5類的作用域3.2.6自引用指針3.2.1對象的定義C++中,可以用以下兩種方式定義:(1)在聲明類時(shí),直接在類體右“}”后定義屬于該類的對象名。例如:classPoint{private:intx,y;public:voidsetPoint(int,int);intgetx();intgety();}obj1,obj2;在聲明類Point的同時(shí)直接定義了兩個(gè)對象obj1和obj2。注意,這時(shí)的對象屬于全局對象。(2)聲明類之后,在使用時(shí)再定義對象,一般格式如下:classPoint{…//類體};

…//…voidmain(){Pointobj1,obj2;…//…}在主函數(shù)中為類Point定義了兩個(gè)對象obj1和obj2。關(guān)于對象的定義應(yīng)該注意以下幾個(gè)問題(1)在定義類的同時(shí)定義的對象是全局對象,在使用時(shí)定義的對象為局部對象。(2)一個(gè)類被定義后,并不占內(nèi)存空間;只有當(dāng)類被實(shí)例化生成對象后,對象才占有內(nèi)存空間。3.2.2對象成員的訪問對象成員就是該類所定義的成員,分為數(shù)據(jù)成員和函數(shù)成員。其表示方法分為通過對象訪問成員和通過類指針訪問成員兩種形式。(1)通過對象訪問成員使用運(yùn)算符“.”來實(shí)現(xiàn),一般格式為:對象名.數(shù)據(jù)成員或?qū)ο竺?函數(shù)成員名(參數(shù)表)(2)通過類指針訪問成員使用運(yùn)算符“->”來實(shí)現(xiàn),一般格式為:對象指針名->數(shù)據(jù)成員或?qū)ο笾羔樏?>函數(shù)成員名(參數(shù)表)。3.2.3類成員的訪問屬性類成員的訪問屬性有三種,即公有類型(public)、私有類型(private)和保護(hù)類型(protected)。1.公有類型說明為公有的成員不但可以被類中的成員函數(shù)訪問,還可以在類的外部通過類的對象進(jìn)行訪問。2.私有類型說明為私有的成員只能被類中的成員函數(shù)訪問,不能在類的外部通過了的對象進(jìn)行訪問。3.保護(hù)類型說明為保護(hù)的成員除了類本身的成員函數(shù)可以訪問外,該類的派生類的成員也可以訪問,但不能在類的外部通過類的成員進(jìn)行訪問。類的成員對類的對象的可見性和對類的成員函數(shù)的可見性是不同的,類的成員函數(shù)可以訪問類的所有成員,無任何限制,而類的對象對類的成員的訪問是受類成員的訪問屬性的制約的。公有成員是類的外部接口,而私有成員和保護(hù)成員是類的內(nèi)部數(shù)據(jù)和內(nèi)部實(shí)現(xiàn),不希望外界訪問。由于類成員訪問屬性的不同,很好的實(shí)現(xiàn)了信息的封裝和數(shù)據(jù)的保護(hù)。3.2.4對象賦值語句對于兩個(gè)類型相同的變量,可以利用賦值語句實(shí)現(xiàn)將一個(gè)變量的值賦給另一個(gè)變量。在類中,同類型的對象也可以進(jìn)行賦值,當(dāng)一個(gè)對象賦值給另一個(gè)對象時(shí),所有的數(shù)據(jù)成員都會逐位復(fù)制?!纠?.4】對象賦值語句#include<iostream>usingnamespacestd;classPoint{private: intx,y;public: voidsetPoint(inta,intb) {x=a;y=b;} voidshow() {cout<<x<<""<<y<<endl;}};voidmain(){ Pointobj1,obj2; obj1.setPoint(1,2); obj2=obj1;//將對象odj1的值賦給odj2 obj1.show(); obj2.show();}程序運(yùn)行結(jié)果是:1212在該程序中,語句“obj2=obj1;”等價(jià)于語句“obj2.x=obj1.x;ob2.y=ob1.y;”賦值時(shí),兩個(gè)對象的類型必須相同,否則編譯時(shí)將出現(xiàn)錯(cuò)誤。兩個(gè)對象之間的賦值,僅僅是這些對象中的數(shù)據(jù)成員相同,而兩個(gè)對象仍然是分離的,因?yàn)閮蓚€(gè)對象分別占用不同的存儲空間。若類的成員是指針類型,則可能出現(xiàn)錯(cuò)誤。3.2.5類的作用域在類的聲明中,一對大括號所形成的作用域稱為類的作用域。在類的作用域中,一個(gè)類的任何成員可以訪問該類的其他成員,一個(gè)類的成員函數(shù)可以不受限制的訪問該類的成員。但在類的外部,對該類的數(shù)據(jù)成員的訪問是受到一定的限制的,有時(shí)候是不允許的,很好的實(shí)現(xiàn)了類的封裝功能。3.2.6自引用指針當(dāng)定義了一個(gè)類的若干對象后,每個(gè)對象都有屬于自己的對象成員,但是,所有對象的成員函數(shù)代碼合用一份。那么成員函數(shù)是怎樣辨別出當(dāng)前調(diào)用自己是哪一個(gè)對象,從而對該對象的數(shù)據(jù)成員而不是對其他對象的數(shù)據(jù)成員進(jìn)行處理呢?原來,C++為成員函數(shù)提供了一個(gè)名字為this的指針,這個(gè)指針為自引用指針。每當(dāng)創(chuàng)建一個(gè)對象時(shí)系統(tǒng)就自動把this指針作為隱含的參數(shù)傳遞給該函數(shù)。不同的對象調(diào)用一個(gè)成員函數(shù)時(shí),C++編譯器將根據(jù)成員函數(shù)的this指針?biāo)赶虻膶ο髞泶_定應(yīng)該引用哪一個(gè)對象的數(shù)據(jù)成員。因此,被存取的必然是指定對象的數(shù)據(jù)成員。3.3構(gòu)造函數(shù)3.3.1構(gòu)造函數(shù)3.3.2成員初始化表3.3.3缺省參數(shù)的構(gòu)造函數(shù)3.3.4缺省的構(gòu)造函數(shù)3.3.1構(gòu)造函數(shù)構(gòu)造函數(shù)是負(fù)責(zé)對象的創(chuàng)建的特殊成員函數(shù),它主要用于為對象分配空間,進(jìn)行初始化。它除了具有一般成員函數(shù)的特征。另外它還具有特殊的性質(zhì):(1)構(gòu)造函數(shù)的名字必須和類名相同。 (2)構(gòu)造函數(shù)可以有一個(gè)或多個(gè)參數(shù),也可以沒有參數(shù),當(dāng)對象初始化時(shí),需要定義帶參數(shù)的構(gòu)造函數(shù)。(3)構(gòu)造函數(shù)的說明可以在類體內(nèi),也可以在類體外,放在類體外的構(gòu)造函數(shù)要在函數(shù)名前要加上“類名::”。(4)構(gòu)造函數(shù)不能指定返回類型,函數(shù)體中不允許有返回值。(5)構(gòu)造函數(shù)可以重載,一個(gè)類可以定義多個(gè)參數(shù)個(gè)數(shù)不同的構(gòu)造函數(shù)。(6)如果一個(gè)類沒有定義任何構(gòu)造函數(shù),那么C++就自動建立一個(gè)默認(rèn)的構(gòu)造函數(shù),僅創(chuàng)建對象而不作任何初始化,默認(rèn)構(gòu)造函數(shù)是空函數(shù),無參數(shù),不能重載。構(gòu)造函數(shù)創(chuàng)建對象有以下兩種方法:1.用構(gòu)造函數(shù)直接創(chuàng)建對象類名對象名[(實(shí)參表)]“類名”與構(gòu)造函數(shù)名相同,“實(shí)參表”是為構(gòu)造函數(shù)提供的實(shí)際參數(shù)。2.利用構(gòu)造函數(shù)創(chuàng)建對象指針時(shí),通過new來實(shí)現(xiàn),一般形式為:類名*指針變量=new類名[(實(shí)參表)]構(gòu)造函數(shù)的名字必須和類名相同,并且是公有函數(shù);構(gòu)造函數(shù)可以不帶參數(shù)的,構(gòu)造函數(shù)不能指定返回類型,甚至void也不可以;構(gòu)造函數(shù)不能顯式的調(diào)用,它是在定義對象時(shí)有系統(tǒng)自動調(diào)用的。3.3.2成員初始化表帶有成員初始化表的構(gòu)造函數(shù)的一般形式為:類名::構(gòu)造函數(shù)名([參數(shù)表])[:(成員初始化表)]{…//構(gòu)造函數(shù)體}成員初始化表的一般形式為:數(shù)據(jù)成員名1(初始值1),數(shù)據(jù)成員名2(初始值2),3.3.3缺省參數(shù)的構(gòu)造函數(shù)對于帶參數(shù)的構(gòu)造函數(shù),在定義對象時(shí)必須給函數(shù)傳遞參數(shù),否則構(gòu)造函數(shù)將不被執(zhí)行。但在實(shí)際使用中,有些構(gòu)造函數(shù)的參數(shù)值通常是不變的,只有在特殊情況下才需要改變它的參數(shù)值,這時(shí)可以將其定義成帶缺省參數(shù)的構(gòu)造函數(shù)。3.3.4缺省的構(gòu)造函數(shù)在實(shí)際應(yīng)用中,通常要給每個(gè)類定義構(gòu)造函數(shù)。如果沒有給沒類定義構(gòu)造函數(shù),則編譯系統(tǒng)會自動生成一個(gè)缺省的構(gòu)造函數(shù)。格式如下:類名::缺省的構(gòu)造函數(shù)名(){}例如,在例3.4中定義的類中沒有定義任何構(gòu)造函數(shù),但在主程序中有下面的語句:

Pointobj1,obj2;這時(shí)系統(tǒng)將自動為類Point生成缺省的構(gòu)造函數(shù):Point::Point(){}并使用這個(gè)缺省的構(gòu)造函數(shù)為obj1和obj1進(jìn)行初始化。系統(tǒng)自動生成的構(gòu)造函數(shù)不帶任何參數(shù),它只能為對象開辟一個(gè)存儲空間,而不能給對象中的數(shù)據(jù)成員賦初值,這時(shí)的初值是隨機(jī)數(shù),程序在運(yùn)行時(shí)可能出現(xiàn)錯(cuò)誤。因此給對象賦初值是非常重要的。說明:(1)對沒有定義構(gòu)造函數(shù)的類,其公有數(shù)據(jù)成員可以用初始化表進(jìn)行初始化。(2)與定義變量類似,在使用缺省的構(gòu)造函數(shù)創(chuàng)建對象時(shí),如果創(chuàng)建的是全局對象或靜態(tài)對象,則對象的所有數(shù)據(jù)成員初始化為0或空,否則,對象的成員是隨機(jī)的。(3)只要一個(gè)類定義了構(gòu)造函數(shù),系統(tǒng)將不會再為其提供缺省的構(gòu)造函數(shù)。3.4析構(gòu)函數(shù)3.4.1析構(gòu)函數(shù)的構(gòu)成和作用3.4.2缺省的析構(gòu)函數(shù)3.4.1析構(gòu)函數(shù)的構(gòu)成和作用類的析構(gòu)函數(shù)由類名稱和邏輯非運(yùn)算符(~)組成。在以下情況下,析構(gòu)函數(shù)會自動被調(diào)用:第一種情況是:如果一個(gè)對象被定義在一個(gè)函數(shù)體內(nèi),當(dāng)這個(gè)函數(shù)結(jié)束時(shí),該對象的析構(gòu)函數(shù)被自動調(diào)用。第二種情況是:若使用new運(yùn)算符動態(tài)創(chuàng)建一個(gè)對象,在使用delete運(yùn)算符釋放時(shí),delete將會自動調(diào)用析構(gòu)函數(shù)。由此,我們總結(jié)出析構(gòu)函數(shù)的特點(diǎn):(1)析構(gòu)函數(shù)的名稱與類名相同,但前面加有非運(yùn)算符“~”,表明其功能和構(gòu)造函數(shù)相反。(2)析構(gòu)函數(shù)的說明可以在類體內(nèi),也可以在類體外。放在類體外的析構(gòu)函數(shù)名前要加上“類名::”。(3)析構(gòu)函數(shù)沒有參數(shù),因此析構(gòu)函數(shù)不能重載,一個(gè)類只能定義一個(gè)析構(gòu)函數(shù)。如果一個(gè)類沒有定義任何析構(gòu)函數(shù),那么C++就自動建立一個(gè)默認(rèn)的析構(gòu)函數(shù),只執(zhí)行清理任務(wù)。(4)默認(rèn)析構(gòu)函數(shù)是空函數(shù),無參數(shù),不能重載。3.4.2缺省的析構(gòu)函數(shù)每個(gè)類必須有一個(gè)析構(gòu)函數(shù)。如果沒有顯式地為一個(gè)類定義析構(gòu)函數(shù),編譯系統(tǒng)會自動生成一個(gè)缺省的析構(gòu)函數(shù)。格式如下:類名::~析構(gòu)函數(shù)名(){}如編譯系統(tǒng)為類Time生成缺省的析構(gòu)函數(shù)如下所示:Time::~Time(){}對于大多數(shù)類而言,缺省的析構(gòu)函數(shù)就能滿足要求,但是,如果在一個(gè)對象完成其操作之前需要做一些內(nèi)部處理,則應(yīng)該顯式地定義析構(gòu)函數(shù)。如:classstring_time{public: string_time(char*) {str=newchar[max_len];} ~string_time() {delete[]str;} voidget_info(char*); voidsent_info(char*);private: char*str; intmax_len;};3.5再談構(gòu)造函數(shù)3.5.1重載構(gòu)造函數(shù)3.5.2拷貝構(gòu)造函數(shù)3.5.3淺拷貝和深拷貝3.5.1重載構(gòu)造函數(shù)如果一個(gè)類中出現(xiàn)了兩個(gè)以上的同名成員函數(shù),則稱為類的成員函數(shù)重載。與一般的成員函數(shù)一樣,C++允許重載構(gòu)造函數(shù)來適應(yīng)不同的場合,這些構(gòu)造函數(shù)之間以它們所帶的參數(shù)的個(gè)數(shù)或類型的不同來區(qū)分。當(dāng)出現(xiàn)構(gòu)造函數(shù)的重載時(shí),基匹配方式同普通函數(shù)的匹配方式一樣。3.5.2拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)是C++引入的一種特殊的構(gòu)造函數(shù),其名稱與類名相同。當(dāng)用一個(gè)已知對象初始化另一個(gè)對象時(shí)系統(tǒng)將自動調(diào)用拷貝構(gòu)造函數(shù)進(jìn)行對象之間的值的拷貝。1.拷貝構(gòu)造函數(shù)的定義拷貝構(gòu)造函數(shù)的一般形式如下:類名::類名(const類名&對象名){//拷貝構(gòu)造函數(shù)的函數(shù)體}看下面的例子,理解拷貝構(gòu)造函數(shù)的應(yīng)用:classPoint{private: intx,y;public: Point(inta,intb){ x=a;y=b; cout<<"Usingnormalconstructor"<<endl;} Point(constPoint&obj) {x=2*obj.x;y=2*obj.y; cout<<"Usingcopyconstructor:"<<endl; }//……};假如,obj1、obj2為類Point的兩個(gè)對象,而且obj1已經(jīng)存在,則下述語句則可以調(diào)用拷貝構(gòu)造函數(shù)來初始化obj2:Pointobj2(obj1);2.缺省的拷貝構(gòu)造函數(shù)如果一個(gè)類沒有定義任何拷貝構(gòu)造函數(shù),那么C++就自動建立一個(gè)默認(rèn)拷貝構(gòu)造函數(shù)。該函數(shù)的功能是將已知對象的所有數(shù)據(jù)成員的值拷貝給相應(yīng)對象的所有數(shù)據(jù)成員。3.調(diào)用拷貝構(gòu)造函數(shù)我們知道,普通的構(gòu)造函數(shù)是在創(chuàng)建時(shí)被調(diào)用,而拷貝構(gòu)造函數(shù)在以下3種情況下都會被調(diào)用:(1)當(dāng)用類的一個(gè)對象去初始化該類的另一個(gè)對象時(shí)。如:Studentobj2(obj1);//用對象obj1初始化對象obj2,拷貝構(gòu)造函數(shù)被調(diào)用(代入法)Studentobj3=obj1;//用對象obj1初始化對象obj3,拷貝構(gòu)造函數(shù)被調(diào)用(賦值法)(2)當(dāng)函數(shù)的形參是類的對象,調(diào)用函數(shù),進(jìn)行形參和實(shí)參結(jié)合時(shí)。//……fun1(Studentobj)//函數(shù)的形參是類的對象{obj.Student();}main(){Studentobj1(10,20);fun1(obj1);//當(dāng)調(diào)用函數(shù),進(jìn)行形參和實(shí)參結(jié)合時(shí),調(diào)用拷貝構(gòu)造函數(shù)return0;}(3)當(dāng)函數(shù)的返回值是對象,函數(shù)執(zhí)行完成,返回調(diào)用者時(shí)

//……Studentfun2(){Studentobj1(10,30);returnobj1;//返回值是對象}main(){Studentobj2;obj2=fun2();//函數(shù)執(zhí)行完成,返回調(diào)用者時(shí),調(diào)用拷貝構(gòu)造函數(shù)return0;}3.5.3淺拷貝和深拷貝由缺省的拷貝構(gòu)造函數(shù)所實(shí)現(xiàn)的數(shù)據(jù)成員逐一賦值。通常缺省的拷貝構(gòu)造函數(shù)是能夠勝任工作的,但若類中喊有指針類型的數(shù)據(jù),這種按數(shù)據(jù)成員逐一賦值的方法將會產(chǎn)生錯(cuò)誤。3.6程序舉例【實(shí)例1】編寫一個(gè)程序,輸入N個(gè)學(xué)生數(shù)據(jù),包括學(xué)號、姓名、成績,要求輸出這些學(xué)生數(shù)據(jù)并計(jì)算平均分。分析:設(shè)計(jì)一個(gè)學(xué)生類Stud,除了包括no(學(xué)號)、name(姓名)和deg(成績)數(shù)據(jù)成員外,有兩個(gè)靜態(tài)變量sum和num,分別存放總分和人數(shù),另有兩個(gè)普通成員函數(shù)setdata()和disp(),分別用于給數(shù)據(jù)成員賦值和輸出數(shù)據(jù)成員的值,另有一個(gè)靜態(tài)成員函數(shù)avg(),它用于計(jì)算平均分。在main()函數(shù)中定義了一個(gè)對象數(shù)組用于存儲輸入的學(xué)生數(shù)據(jù)。本題程序如下:#include<iostream>usingnamespacestd;#include<stdio.h>#include<string.h>#defineN3classStud{intno;charname[10];intdeg;staticintnum;staticintsum;public:voidsetdata(intn,charna[],intd){no=n;deg=d;strcpy(name,na);sum+=d;num++;}staticdoubleavg(){returnsum/num;}voiddisp(){cout<<no<<name<<deg;}};intStud::sum=0;intStud::num=0;voidmain(){Studst[N];inti,n,d;

charna[10];for(i=0;i<N;i++)

{cout<<"輸入學(xué)號姓名成績:";

cout<<&n<<na<<&d;st[i].setdata(n,na,d);}cout<<"輸出數(shù)據(jù)\n";cout<<"學(xué)號姓名成績\n";for(i=0;i<N;i++)st[i].disp();cout<<"平均分="<<Stud::avg();}本程序的執(zhí)行結(jié)果如下:輸入學(xué)號姓名成績:1stud189輸入學(xué)號姓名成績:2stud278輸入學(xué)號姓名成績:3stud84輸出數(shù)據(jù)學(xué)號姓名成績

1stud1892stud2783stud384平均分=833.7本章小結(jié)(1)C++中引進(jìn)了類的概念,將數(shù)據(jù)和與之相關(guān)的函數(shù)封裝在一起,避免了C結(jié)構(gòu)中的不安全性,實(shí)現(xiàn)了數(shù)據(jù)的保護(hù)和權(quán)限控制,形成了一個(gè)統(tǒng)一體,具有良好的外部接口。(2)根據(jù)訪問權(quán)限可以將數(shù)據(jù)成員和成員函數(shù)劃分為3種,即:公有數(shù)據(jù)成員和公有成員函數(shù)、保護(hù)數(shù)據(jù)成員和保護(hù)成員函數(shù)以及私有數(shù)據(jù)成員和私有成員函數(shù)。通常情況下,一個(gè)類的數(shù)據(jù)成員聲明為私有成員或保護(hù)成員,可以使數(shù)據(jù)得到有效的保護(hù);成員函數(shù)一般都聲明公有成員,作為類與外界的接口。(3)類與對象有著密切的聯(lián)系,類是用戶聲明的一種抽象的數(shù)據(jù)類型,對象是類的一個(gè)實(shí)例。在定義對象時(shí)有兩種方法:①在聲明類的同時(shí),直接定義對象——在聲明類的右花括號“}”后直接寫出對象名。注意,此時(shí)定義的對象是一個(gè)全局對象。②聲明類以后,在使用時(shí)定義對象。此時(shí)定義的對象為局部對象。(4)構(gòu)造函數(shù)和析構(gòu)函數(shù)都是類的特殊的成員函數(shù),構(gòu)造函數(shù)的作用是創(chuàng)建對象時(shí)進(jìn)行初始化,析構(gòu)函數(shù)的作用是釋放對象時(shí)清理現(xiàn)場。構(gòu)造函數(shù)是在定義對象的同時(shí)被調(diào)用的,如果沒有給類定義構(gòu)造函數(shù),系統(tǒng)會自動生成一個(gè)缺省的構(gòu)造函數(shù)。每個(gè)類必須有一個(gè)析構(gòu)函數(shù)。如果沒有顯式地為一個(gè)類定義析構(gòu)函數(shù),編譯系統(tǒng)會自動生成一個(gè)缺省的析構(gòu)函數(shù)。C++中有多種構(gòu)造函數(shù),如缺省構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、缺省拷貝構(gòu)造函數(shù)等,他們都有各自不同的特點(diǎn)和用途。(5)所謂淺拷貝就是由缺省的拷貝構(gòu)造函數(shù)所實(shí)現(xiàn)的數(shù)據(jù)成員逐一賦值。若類中含有指針類型的數(shù)據(jù),這種方法將會產(chǎn)生錯(cuò)誤。為了解決淺拷貝出現(xiàn)的錯(cuò)誤,必須顯式地定義一個(gè)自己的拷貝構(gòu)造函數(shù),使之不但拷貝數(shù)據(jù)成員,而且為對象分配各自的內(nèi)存空間,這就是所謂的深拷貝。習(xí)題三習(xí)題三一、填空題1.OOP技術(shù)由

、

、方法、消息和繼承五個(gè)基本的概念所組成。2.類的成員函數(shù)可以在

定義,也可以在

定義。3.一個(gè)類的析構(gòu)函數(shù)不允許有

。4.建立對象時(shí),為節(jié)省內(nèi)存,系統(tǒng)只給_______分配內(nèi)存。5.類中的數(shù)據(jù)和成員函數(shù)默認(rèn)訪問類型為

溫馨提示

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

評論

0/150

提交評論