第4章類和對象(一)_第1頁
第4章類和對象(一)_第2頁
第4章類和對象(一)_第3頁
第4章類和對象(一)_第4頁
第4章類和對象(一)_第5頁
已閱讀5頁,還剩41頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第4章類和對象(一)4.1類的構(gòu)成類構(gòu)成了實(shí)現(xiàn)C++面向?qū)ο蟪绦蛟O(shè)計的基礎(chǔ),在C++語言面向?qū)ο蟪绦蛟O(shè)計中占據(jù)著核心地位。它把數(shù)據(jù)和作用在這些數(shù)據(jù)上的操作組合在一起,是封裝的基本單元。對象是類的實(shí)例,類定義了屬于該類的所有對象的共同特性。例4.1有關(guān)日期結(jié)構(gòu)的例子。#include<iostream.h>structDate{

intyear;

intmonth;

intday;};voidmain(){Datedate1;date1.year=2006;date1.month=2;date1.day=25;

cout<<date1.year<<"."<<date1.month<<"."<<date1.day<<endl;}4.1.1從結(jié)構(gòu)到類

除該類的成員函數(shù)外,誰都不得訪問程序中所有函數(shù)都可訪問4.1.2類的構(gòu)成

與結(jié)構(gòu)不同之處是成員訪問說明符類是一種用戶自定義的數(shù)據(jù)類型,聲明格式如下:class類名

{public:

公有數(shù)據(jù)成員;

公有成員函數(shù);protected:

保護(hù)數(shù)據(jù)成員;

保護(hù)成員函數(shù);private:

私有數(shù)據(jù)成員;

私有成員函數(shù);};該類的派生類的成員也可以訪問可以省去

stacksta1;stack*pstack=newstack;堆棧的類版本:

classstack{

private:charv[100];char*p;

public:voidpush(charc){//……}charpop(){//……}};4.1.2類的構(gòu)成(續(xù))

用一個類來描述日期,其形式如下:classDate{public:voidsetDate(int

y,int

m,intd); voidshowDate();private:

intyear;

intmonth;

intday;};

4.2成員函數(shù)的聲明成員函數(shù)的聲明通常采用以下兩種方式:

(1)將成員函數(shù)以普通函數(shù)的形式進(jìn)行說明,這種成員函數(shù)在類外定義的一般形式是:

返回類型類名∷成員函數(shù)名(參數(shù)表){

//函數(shù)體

}類名和成員函數(shù)名前加上作用域限定符::

例如,以下是表示坐標(biāo)點(diǎn)的類Coord的聲明。

classCoord{public:

voidsetCoord(int,int);//設(shè)置坐標(biāo)點(diǎn)

int

getx();//取x坐標(biāo)點(diǎn)

int

gety();//取y坐標(biāo)點(diǎn)

private:

intx,y;};

voidCoord∷setCoord(int

a,intb){x=a;y=b;}

int

Coord::getx(){returnx;}

int

Coord::gety(){returny;}

setCoord、getx()、gety()雖然寫在類外,但均屬于coord的成員函數(shù),可以直接使用coord中的數(shù)據(jù)成員x,y。

(2)以內(nèi)聯(lián)函數(shù)的形式進(jìn)行說明。在C++中,可以用兩種格式將成員函數(shù)聲明為類的內(nèi)聯(lián)函數(shù):

①隱式聲明直接將函數(shù)聲明在類內(nèi)部。②

顯式聲明

這種成員函數(shù)在類外定義的一般形式是:inline返回類型類名::成員函數(shù)名(參數(shù)表){

//函數(shù)體}

4.3對象的定義和使用

4.3.1類與對象的關(guān)系 通常我們把具有共同屬性和行為的事物所構(gòu)成的集合叫做類。在C++中,可以把相同數(shù)據(jù)結(jié)構(gòu)和相同操作集的對象看成屬于同一類。

4.3.2對象的定義

(1)在聲明類時,直接定義對象。此時定義的對象為全局對象。例如:classCoord{public:voidsetCoord(int,int);

int

getx();

int

gety();private:

intx,y;}op1,op2;

(2)聲明了類之后,在使用時再定義對象,定義的格式與一般變量的定義格式相同。例如:classCoord{//…};//…main(){

Coordop1,op2;//…}4.3.3對象中成員的訪問

在類外通過類的對象訪問公有數(shù)據(jù)成員或成員函數(shù),一般形式是:

對象名.數(shù)據(jù)成員名或

對象名.成員函數(shù)名(參數(shù)表)

例4.2使用類Coord的完整程序。

#include<iostream.h>classCoord{ public: voidsetCoord(int

a,intb){x=a;y=b;}

int

getx(){returnx;}

int

gety(){returny;}

private:

intx,y;}; voidmain() {Coordop1;

int

i,j; op1.x=3; op1.y=4; op1.setCoord(5,6);//調(diào)用op1的setCoord(),初始化對象op1 i=op1.getx();//調(diào)用op1的getx(),取op1的x值

j=op1.gety();//調(diào)用op1的gety(),取op1的y值

cout<<"op1i="<<i<<"op1j="<<j<<endl;}類的對象不能訪問私有成員

4.3.4類成員的訪問屬性

類成員三種訪問屬性:公有(public)私有(private)保護(hù)(protected)

類的成員函數(shù)可以訪問類的所有成員,無限制;而類的對象對類的成員的訪問是受成員的訪問屬性的制約。4.3.5對象賦值語句例4.5用對象賦值語句的例子。

#include<iostream.h>classabc{

public:voidinit(inti,intj){a=i;b=j;}voidshow(){cout<<a<<""<<b<<endl;}

private:I inta,b;}; main() {abco1,o2; o1.init(12,34); o2=o1;

//將對象o1數(shù)據(jù)成員的值賦給對象o2 o1.show(); o2.show(); return0; }等價于o2.a=o1.a;o2.b=o1.b幾點(diǎn)說明:對象賦值時,兩個對象的類型必須相同,否則編譯會出錯;兩個對象之間的賦值,僅僅使這些對象中數(shù)據(jù)成員相同,而對象仍是分離的。4.3.6類的作用域

一個類的所有成員都在該類的作用域內(nèi),一個類的任何成員可以訪問該類的其他成員。類外對該類的數(shù)據(jù)成員和成員函數(shù)的訪問受到一定的限制,甚至是不允許的,這體現(xiàn)了類的封裝功能。例4.6理解類的作用域。#include<iostream.h>classmyclass{public:

inti;voidinit(int);voidshow(){cout<<“i=”<<i<<endl;}};voidmyclass::init(int

si){i=si;}

intfun(){returni;}voidmain(){myclassob;ob.init(5);ob.show();i=8;

ob.show();}可以訪問類中的數(shù)據(jù)成員i可以訪問類中的數(shù)據(jù)成員i給數(shù)據(jù)成員i賦初值5非法,不能直接訪問類中的i,可改寫成ob.i=8非法,不能直接訪問類中的i3.4構(gòu)造函數(shù)與析構(gòu)函數(shù)

構(gòu)造函數(shù)和析構(gòu)函數(shù)都是類的成員函數(shù),但它們都是特殊的成員函數(shù),執(zhí)行特殊的功能,不用調(diào)用便自動執(zhí)行,而且這些函數(shù)的名字與類的名字有關(guān)。

4.4.1構(gòu)造函數(shù)

構(gòu)造函數(shù)是一種特殊的成員函數(shù),它主要用于為對象分配空間,進(jìn)行初始化。構(gòu)造函數(shù)具有一些特殊的性質(zhì):構(gòu)造函數(shù)名與類名相同。構(gòu)造函數(shù)可以有任意類型的參數(shù),但不能指定返回類型。可以重載,即一個類中可以定義多個參數(shù)個數(shù)或參數(shù)類型不同的構(gòu)造函數(shù)。構(gòu)造函數(shù)被聲明為公有函數(shù),但它不能像其他成員函數(shù)那樣被顯式地調(diào)用,它是在定義對象的同時被自動調(diào)用的。例4.7為類Date建立一個構(gòu)造函數(shù)。classDate{public:

Date(int

y,int

m,intd);//構(gòu)造函數(shù)

voidsetDate(int

y,int

m,intd);voidshowDate()private:

intyear,month,day;};Date::Date(int

y,int

m,intd)//構(gòu)造函數(shù)的實(shí)現(xiàn)

{year=y;month=m;day=d;}voidDate::setDate(int

y,int

m,intd){year=y;month=m;day=d;}inlinevoidDate::showDate(){cout<<year<<"."<<month<<"."<<day<<endl;}

構(gòu)造函數(shù)創(chuàng)建對象有以下兩種方法:

(1)利用構(gòu)造函數(shù)直接創(chuàng)建對象

類名對象名[(實(shí)參表)];

其中,“類名”與構(gòu)造函數(shù)名相同,“實(shí)參表”是為構(gòu)造函數(shù)提供的實(shí)際參數(shù)。(2)通過指針和new來實(shí)現(xiàn)類名*指針變量=new類名[(實(shí)參表)];

如:Date*date1=newDate(1998,4,28);date1->showDate();例4.8利用構(gòu)造函數(shù)直接創(chuàng)建對象。#include<iostream.h>classDate{//省略,同例4.7

};

//省略,同例4.7voidmain(){

Datedate1(1998,4,28);

/*定義類Date的對象date1,

自動調(diào)用date1的構(gòu)造函數(shù),初始化對象date1*/

cout<<"Date1output1:"<<endl;date1.showDate();

//調(diào)用date1的showDate(),顯示date1的數(shù)據(jù)

date1.SetDate(2002,11,14);

//調(diào)用date1的setDate(),重新設(shè)置date1的數(shù)據(jù)

cout<<"Date1output2:"<<endl;date1.showDate();

//調(diào)用date1的showDate(),顯示date1的數(shù)據(jù)}

將例4.8的主函數(shù)改成用這種方法來實(shí)現(xiàn),其運(yùn)行結(jié)果與原例題完全相同。voidmain(){ Date*date1;date1=newDate(1998,4,28);

//以上兩條語句可合寫成:Date*date1=newDate(1998,4,28);

cout<<"Date1output1:"<<endl; date1->showDate(); date1->setDate(2002,11,14);

cout<<"Date1output2:"<<endl; date1->showDate(); deletedate1;}⑤構(gòu)造函數(shù)也可以沒有參數(shù),稱為缺省構(gòu)造函數(shù)。classDate{public:Date()//缺省構(gòu)造函數(shù)

{year=1996;month=1;day=22;}voidshowDate()private:

intyear,month,day;};inlinevoidDate::showDate(){cout<<year<<"."<<month<<"."<<day<<endl;}voidmain(){Dated2; d2.showDate();}

1、為d2分配空間

2、調(diào)用構(gòu)造函數(shù)(注:不能寫成

Dated2();)4.4.2成員初始化表

常量類型及引用類型的數(shù)據(jù)成員不能在構(gòu)造函數(shù)中用賦值語句直接賦值,需用帶有成員初始化表的構(gòu)造函數(shù)的一般形式如下:類名::構(gòu)造函數(shù)名([參數(shù)表])[:(成員初始化表)]{

//構(gòu)造函數(shù)體

}成員初始化表的一般形式為:

數(shù)據(jù)成員名1(初始值1),數(shù)據(jù)成員名2(初始值2),……例4.9成員初始化表的使用。#include<iostream.h>classA{private:

intx;int&

rx;constfloatpi;public:

A(intx1):x(x1),rx(x),pi(3.14)

//rx(x)相當(dāng)于rx=x,{}//pi(3.14)相當(dāng)于pi=3.14voidprint(){cout<<"x="<<x<<""<<"rx="<<rx<<""<<"pi="<<pi;}};main(){Aa(10);a.print();return0;}

以下程序的運(yùn)行結(jié)果:#include<iostream.h>classA{private:

intt1,t2;public: A(inti):t2(i),t1(t2+1) {cout<<"t1="<<t1<<"t2="<<t2<<endl;}};voidmain(){ Aa1(10);}?運(yùn)行結(jié)果類成員是按照它們在類中被聲明的順序進(jìn)行初始化的,與它們在成員初始化表中列出的順序無關(guān)。由于t1在t2前聲明,因此,t2在還沒有初始化時,t1使用t2的值來初始化,結(jié)果是隨機(jī)值。4.4.3析構(gòu)函數(shù)

析構(gòu)函數(shù)也是一種特殊的成員函數(shù)。它執(zhí)行與構(gòu)造函數(shù)相反的操作,通常用于撤消對象時的一些清理任務(wù),如釋放分配給對象的內(nèi)存空間等。

析構(gòu)函數(shù)有以下一些特點(diǎn):析構(gòu)函數(shù)前以波浪號(~)作標(biāo)志;析構(gòu)函數(shù)與構(gòu)造函數(shù)名字相同;析構(gòu)函數(shù)沒有參數(shù),也沒有返回值,而且不能重載。因此,在一個類中只能有一個析構(gòu)函數(shù);當(dāng)撤消對象時,編譯系統(tǒng)自動地調(diào)用析構(gòu)函數(shù)。例4.12重新說明類Date。#include<iostream.h>classDate{public:

Date(int

y,int

m,intd);//構(gòu)造函數(shù)

~Date();//析構(gòu)函數(shù)

voidsetDate(int

y,int

m,intd); voidshowDate();private:

intyear,month,day;};Date::Date(int

y,int

m,intd)//構(gòu)造函數(shù)的實(shí)現(xiàn)

{cout<<"constructing..."<<endl;year=y;month=m;day=d;}Date::~Date()//析構(gòu)函數(shù)的實(shí)現(xiàn)

{cout<<"destruting..."<<endl;}voidDate::setDate(int

y,int

m,intd){year=y;month=m;day=d;}inlinevoidDate::showDate() {cout<<year<<"."<<month<<"."<<day<<endl;}voidmain(){Datedate1(1998,4,28);//定義類Date的對象date1,//調(diào)用date1的構(gòu)造函數(shù),初始化對象date1

cout<<"Date1output1:"<<endl;date1.showDate();

//調(diào)用date1的showDate(),顯示date1的數(shù)據(jù)

date1.setDate(2002,11,14);//調(diào)用date1的setDate(),

//重新設(shè)置date1的數(shù)據(jù)

cout<<"Date1output2:"<<endl;date1.showDate();

//調(diào)用date1的showDate(),顯示date1的數(shù)據(jù)}說明:

以下情況中析構(gòu)函數(shù)也會被自動調(diào)用:如果一個對象被定義在一個函數(shù)體內(nèi),則當(dāng)這個函數(shù)結(jié)束時,該對象的析構(gòu)函數(shù)自動被調(diào)用。若一個對象使用new運(yùn)算符動態(tài)創(chuàng)建,在使用delete釋放它時也會自動調(diào)用。4.4.4缺省的構(gòu)造函數(shù)和缺省的析構(gòu)函數(shù)

1.缺省的構(gòu)造函數(shù)在實(shí)際應(yīng)用中,如果沒有給類定義構(gòu)造函數(shù),則編譯系統(tǒng)自動地生成一個缺省的構(gòu)造函數(shù)。其格式如下:

類名::缺省構(gòu)造函數(shù)名(){}

2.缺省的析構(gòu)函數(shù)

每個類必須有一個析構(gòu)函數(shù)。若沒有顯式地為一個類定義析構(gòu)函數(shù),編譯系統(tǒng)會自動地生成一個缺省的析構(gòu)函數(shù),其格式如下:

類名::析構(gòu)函數(shù)名(){}4.4.5重載構(gòu)造函數(shù)

例4.17重載構(gòu)造函數(shù)應(yīng)用例程。#include<iostream.h>classDate{public:

Date();//無參數(shù)的構(gòu)造函數(shù)

Date(int

y,int

m,intd);//帶有參數(shù)的構(gòu)造函數(shù)

voidshowDate();private:

intyear,month,day;};Date::Date(){year=1998;month=4;day=28;}Date::Date(inty,intm,intd){year=y;month=m;day=d;}inlinevoidDate::showDate(){cout<<year<<"."<<month<<"."<<day<<endl;}4.4.6拷貝構(gòu)造函數(shù)

拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),其形參是本類對象的引用。其作用是使用一個已經(jīng)存在的對象去初始化另一個同類的對象。

拷貝構(gòu)造函數(shù)具有以下特點(diǎn):函數(shù)名與類名相同,并且該函數(shù)無返回值類型。該函數(shù)只有一個參數(shù),且是同類對象的引用。每個類都必須有一個拷貝構(gòu)造函數(shù)??筛鶕?jù)需要定義特定的拷貝構(gòu)造函數(shù),以實(shí)現(xiàn)同類對象之間數(shù)據(jù)成員的傳遞。如果沒有定義類的拷貝構(gòu)造函數(shù),系統(tǒng)就會自動生成產(chǎn)生一個缺省的拷貝構(gòu)造函數(shù)。

1.自定義拷貝構(gòu)造函數(shù)自定義拷貝構(gòu)造函數(shù)的一般形式如下:

類名::類名(類名&對象名)

{

//拷貝構(gòu)造函數(shù)的函數(shù)體

}例4.19自定義拷貝構(gòu)造函數(shù)的使用。

#include<iostream.h> classCoord { public:

Coord(int

a,intb)//構(gòu)造函數(shù)

{x=a;y=b;cout<<"Usingnormalconstructor\n";}

Coord(const

Coord&p)//拷貝構(gòu)造函數(shù)

{x=2*p.x;y=2*p.y;cout<<"Usingcopyconstructor\n";} voidprint(){cout<<x<<""<<y<<endl;}private:

intx,y;}; main() {Coordp1(30,40);//定義對象p1,調(diào)用了普通的構(gòu)造函數(shù)

Coordp2(p1);//以“代入”法調(diào)用拷貝構(gòu)造函數(shù),

用對象p1初始化對象p2 p1.print();p2.print(); return0; }

2.缺省的拷貝構(gòu)造函數(shù)

如果沒有編寫自定義的拷貝構(gòu)造函數(shù),C++會自動地將一個已存在的對象復(fù)制給新對象,這種按成員逐一復(fù)制的過程由是缺省拷貝構(gòu)造函數(shù)自動完成的。

例4.20調(diào)用缺省的拷貝構(gòu)造函數(shù)。#include<iostream.h>classCoord{public:

Coord(int

a,intb){x=a;y=b;cout<<"Usingnormalconstructor\n";}voidprint(){cout<<x<<""<<y<<endl;}private:

intx,y;};main(){Coordp1(30,40);//定義類Coord的對象p1,

//調(diào)用了普通構(gòu)造函數(shù)初始化對象p1

Coordp2(p1);

//以“代入”法調(diào)用缺省的拷貝構(gòu)造函數(shù),用對象p1初始化對象p2

Coordp3=p1;

//以“賦值”法調(diào)用缺省的拷貝構(gòu)造函數(shù),用對象p1初始化對象p3p1.print();p2.print();p3.print();return0;}3.調(diào)用拷貝構(gòu)造函數(shù)的三種情況

(1)聲明語句中用一個對象初始化另一個對象。如例4.20主函數(shù)main()中的下述語句:

Coordp2(p1);//用對象p1初始化對象p2,

拷貝構(gòu)造函數(shù)被調(diào)用(代入法)

Coordp3=p1;//用對象p1初始化對象p3,

拷貝構(gòu)造函數(shù)被調(diào)用(賦值法)

這時需要調(diào)用拷貝構(gòu)造函數(shù)。

(2)將一個對象作為參數(shù)按值調(diào)用方式傳遞給另一個對象時生成對象副本。當(dāng)對象作為函數(shù)實(shí)參傳遞給函數(shù)形參時,如p=f(N),在調(diào)用f()函數(shù)時,對象N是實(shí)參,要用它來初始化被調(diào)用函數(shù)的形參,這時需要調(diào)用拷貝構(gòu)造函數(shù)。例如://…fun1(Coordp)//函數(shù)的形參是類的對象

{p.print();}main(){

Coordp1(10,20);fun1(p1);//當(dāng)調(diào)用函數(shù),進(jìn)行形參和實(shí)參結(jié)合時,

調(diào)用拷貝構(gòu)造函數(shù)

return0;}(3)

溫馨提示

  • 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論