詳解C++中的對象指針與對象數(shù)組
C++對象指針
指向?qū)ο蟮闹羔?/p>
在建立對象時,編譯系統(tǒng)會為每一個對象分配一定的存儲空間,以存放其成員。對象空間的起始地址就是對象的指針??梢远x一個指針變量,用來存放對象的指針。
如果有一個類:
class Time
{
public :
int hour;
int minute;
int sec;
void get_time( );
};
void Time::get_time( )
{
cout<<hour<<":"<<minute<<":"<<sec<<endl;
}
在此基礎(chǔ)上有以下語句:
Time *pt; //定義pt為指向Time類對象的指針變量 Time t1; //定義t1為Time類對象 pt=&t1; //將t1的起始地址賦給pt
這樣,pt就是指向Time類對象的指針變量,它指向?qū)ο髏1。
定義指向類對象的指針變量的一般形式為:
類名 *對象指針名;
可以通過對象指針訪問對象和對象的成員。如:
*pt //pt所指向的對象,即t1 (*pt).hour //pt所指向的對象中的hour成員,即t1.hour pt->hour //pt所指向的對象中的hour成員,即t1.hour (*pt).get_time ( ) //調(diào)用pt所指向的對象中的get_time函數(shù),即t1.get_time pt->get_time ( ) //調(diào)用pt所指向的對象中的get_time函數(shù),即t1.get_time
上面第2, 3行的作用是等價的,第4, 5兩行也是等價的。
指向?qū)ο蟪蓡T的指針
對象有地址,存放對象初始地址的指針變量就是指向?qū)ο蟮闹羔樧兞?。對象中的成員也有地址,存放對象成員地址的指針變量就是指向?qū)ο蟪蓡T的指針變量。
1) 指向?qū)ο髷?shù)據(jù)成員的指針
定義指向?qū)ο髷?shù)據(jù)成員的指針變量的方法和定義指向普通變量的指針變量方法相同。例如:
int *p1; //定義指向整型數(shù)據(jù)的指針變量
定義指向?qū)ο髷?shù)據(jù)成員的指針變量的一般形式為:
數(shù)據(jù)類型名 *指針變量名;
如果Time類的數(shù)據(jù)成員hour為公用的整型數(shù)據(jù),則可以在類外通過指向?qū)ο髷?shù)據(jù)成員的指針變量訪問對象數(shù)據(jù)成員hour:
p1=&t1.hour; //將對象t1的數(shù)據(jù)成員hour的地址賦給p1,p1指向t1.hour cout<<*p1<<endl; //輸出t1.hour的值
2) 指向?qū)ο蟪蓡T函數(shù)的指針
需要提醒讀者注意: 定義指向?qū)ο蟪蓡T函數(shù)的指針變量的方法和定義指向普通函數(shù)的指針變量方法有所不同。這里重溫一個指向普通函數(shù)的指針變量的定義方法:
數(shù)據(jù)類型名 (*指針變量名) (參數(shù)表列);
如
void ( *p)( ); //p是指向void型函數(shù)的指針變量
可以使它指向一個函數(shù),并通過指針變量調(diào)用函數(shù):
p = fun; //將fun函數(shù)的人口地址傳給指針變童p,p就指向了函數(shù)fn
(*P)( ); //調(diào)用fn函數(shù)
而定義一個指向?qū)ο蟪蓡T函數(shù)的指針變量則比較復(fù)雜一些。如果模仿上面的方法將對象成員函數(shù)名賦給指針變最P:
p = t1.get_time;
則會出現(xiàn)編譯錯誤。為什么呢?
成員函數(shù)與普通函數(shù)有一個最根本的區(qū)別: 它是類中的一個成員。編譯系統(tǒng)要求在上面的賦值語句中,指針變量的類型必須與賦值號右側(cè)函數(shù)的類型相匹配,要求在以下3方面都要匹配:
①函數(shù)參數(shù)的類型和參數(shù)個數(shù);
②函數(shù)返回值的類型;
③所屬的類。
現(xiàn)在3點中第①②兩點是匹配的,而第③點不匹配。指針變量p與類無關(guān),面get_ time函數(shù)卻屬于Time類。因此,要區(qū)別普通函數(shù)和成員函數(shù)的不同性質(zhì),不能在類外直接用成員函數(shù)名作為函數(shù)入口地址去調(diào)用成員函數(shù)。
那么,應(yīng)該怎樣定義指向成員函數(shù)的指針變量呢?應(yīng)該采用下面的形式:
void (Time::*p2)( ); //定義p2為指向Time類中公用成員函數(shù)的指針變量
注意:(Time:: *p2) 兩側(cè)的括號不能省略,因為()的優(yōu)先級高于*。如果無此括號,就相當于:
void Time::*(p2()) //這是返回值為void型指針的函數(shù)
定義指向公用成員函數(shù)的指針變量的一般形式為:
數(shù)據(jù)類型名 (類名::*指針變量名)(參數(shù)表列);
可以讓它指向一個公用成員函數(shù),只需把公用成員函數(shù)的入口地址賦給一個指向公用成員函數(shù)的指針變量即可。如:
p2=&Time::get_time;
使指針變量指向一個公用成員函數(shù)的一般形式為
指針變量名=&類名::成員函數(shù)名;
在VC++系統(tǒng)中,也可以不寫&,以和C語言的用法一致,但建議在寫C++程序時不要省略&。
[例]有關(guān)對象指針的使用方法。
#include <iostream>
using namespace std;
class Time
{
public:
Time(int,int,int);
int hour;
int minute;
int sec;
void get_time( );
};
Time::Time(int h,int m,int s)
{
hour=h;
minute=m;
sec=s;
}
void Time::get_time( ) //聲明公有成員函數(shù)
//定義公有成員函數(shù)
{
cout<<hour<<":"<<minute<<":" <<sec<<endl;
}
int main( )
{
Time t1(10,13,56); //定義Time類對象t1
int *p1=&t1.hour; //定義指向整型數(shù)據(jù)的指針變量p1,并使p1指向t1.hour
cout<<* p1<<endl; //輸出p1所指的數(shù)據(jù)成員t1.hour
t1.get_time( ); //調(diào)用對象t1的成員函數(shù)get_time
Time *p2=&t1; //定義指向Time類對象的指針變量p2,并使p2指向t1
p2->get_time( ); //調(diào)用p2所指向?qū)ο?即t1)的get_time函數(shù)
void (Time::*p3)( ); //定義指向Time類公用成員函數(shù)的指針變量p3
p3=&Time::get_time; //使p3指向Time類公用成員函數(shù)get_time
(t1.*p3)( ); //調(diào)用對象t1中p3所指的成員函數(shù)(即t1.get_time( ))
return 0;
}
程序運行結(jié)果為:
10 (main函數(shù)第4行的輸出) 10:13:56 (main函數(shù)第5行的輸出) 10:13:56 (main函數(shù)第7行的輸出) 10:13:56 (main函數(shù)第10行的輸出)
可以看到為了輸出t1中hour,minute和sec的值,可以采用3種不同的方法。
幾點說明:
1) 從main函數(shù)第9行可以看出,成員函數(shù)的入口地址的正確寫法是:
&類名::成員函數(shù)名
不應(yīng)該寫成:
p3 =&t1.get_time; //t1為對象名
成員函數(shù)不是存放在對象的空間中的,而是存放在對象外的空間中的。如果有多個同類的對象,它們共用同一個函數(shù)代碼段。因此賦給指針變量p3的應(yīng)是這個公用的函數(shù)代碼段的入口地址。
調(diào)用t1的get_time函數(shù)可以用t1.get_time()形式,那是從邏輯的角度而言的,通過對象名能調(diào)用成員函數(shù)。而現(xiàn)在程序語句中需要的是地址,它是物理的,具體地址是和類而不是對象相聯(lián)系的。
2) main函數(shù)第8, 9兩行可以合寫為一行:
void (Time::*p3)( )=&Time::get_time; //定義指針變量時指定其指向
C++對象數(shù)組
數(shù)組不僅可以由簡單變量組成(例如整型數(shù)組的每一個元素都是整型變量),也可以由對象組成(對象數(shù)組的每一個元素都是同類的對象)。
在日常生活中,有許多實體的屬性是共同的,只是屬性的具體內(nèi)容不同。例如一個班有50個學(xué)生,每個學(xué)生的屬性包括姓名、性別、年齡、成績等。如果為每一個學(xué)生建立一個對象,需要分別取50個對象名。用程序處理很不方便。這時可以定義一個“學(xué)生類”對象數(shù)組,每一個數(shù)組元素是一個“學(xué)生類”對象。例如
Student stud[50]; //假設(shè)已聲明了Student類,定義stud數(shù)組,有50個元素
在建立數(shù)組時,同樣要調(diào)用構(gòu)造函數(shù)。如果有50個元素,需要調(diào)用50次構(gòu)造函數(shù)。
在需要時可以在定義數(shù)組時提供實參以實現(xiàn)初始化。如果構(gòu)造函數(shù)只有一個參數(shù),在定義數(shù)組時可以直接在等號后面的花括號內(nèi)提供實參。如
Student stud[3]={60,70,78}; //合法,3個實參分別傳遞給3個數(shù)組元素的構(gòu)造函數(shù)
如果構(gòu)造函數(shù)有多個參數(shù),則不能用在定義數(shù)組時直接提供所有實參的方法,因為一個數(shù)組有多個元素,對每個元素要提供多個實參,如果再考慮到構(gòu)造函數(shù)有默認參數(shù)的情況,很容易造成實參與形參的對應(yīng)關(guān)系不清晰,出現(xiàn)歧義性。例如,類Student的構(gòu)造函數(shù)有多個參數(shù),且為默認參數(shù):
Student:: Student(int=1001,int=18,int=60); //定義構(gòu)造函數(shù),有多個參數(shù),且為默認參數(shù)
如果定義對象數(shù)組的語句為
Student stud[3]={1005,60,70};
在程序中最好不要采用這種容易引起歧義性的方法。
編譯系統(tǒng)只為每個對象元素的構(gòu)造函數(shù)傳遞一個實參,所以在定義數(shù)組時提供的實參個數(shù)不能超過數(shù)組元素個數(shù),如
Student stud[3]={60,70,78,45}; //不合法,實參個數(shù)超過對象數(shù)組元素個數(shù)
那么,如果構(gòu)造函數(shù)有多個參數(shù),在定義對象數(shù)組時應(yīng)當怎樣實現(xiàn)初始化呢?回答是: 在花括號中分別寫出構(gòu)造函數(shù)并指定實參。
如果構(gòu)造函數(shù)有3個參數(shù),分別代表學(xué)號、年齡、成績。則可以這樣定義對象數(shù)組:
Student Stud[3]={ //定義對象數(shù)組
Student(1001,18,87), //調(diào)用第1個元素的構(gòu)造函數(shù),為它提供3個實參
Student(1002,19,76), //調(diào)用第2個元素的構(gòu)造函數(shù),為它提供3個實參
Student(1003,18,72) //調(diào)用第3個元素的構(gòu)造函數(shù),為它提供3個實參
};
在建立對象數(shù)組時,分別調(diào)用構(gòu)造函數(shù),對每個元素初始化。每一個元素的實參分別用括號包起來,對應(yīng)構(gòu)造函數(shù)的一組形參,不會混淆。
[例] 對象數(shù)組的使用方法。
#include <iostream>
using namespace std;
class Box
{
public :
//聲明有默認參數(shù)的構(gòu)造函數(shù),用參數(shù)初始化表對數(shù)據(jù)成員初始化
Box(int h=10,int w=12,int len=15): height(h),width(w),length(len){ }
int volume( );
private :
int height;
int width;
int length;
};
int Box::volume( )
{
return (height*width*length);
}
int main( )
{
Box a[3]={ //定義對象數(shù)組
Box(10,12,15), //調(diào)用構(gòu)造函數(shù)Box,提供第1個元素的實參
Box(15,18,20), //調(diào)用構(gòu)造函數(shù)Box,提供第2個元素的實參
Box(16,20,26) //調(diào)用構(gòu)造函數(shù)Box,提供第3個元素的實參
};
cout<<"volume of a[0] is "<<a[0].volume( )<<endl;
cout<<"volume of a[1] is "<<a[1].volume( )<<endl;
cout<<"volume of a[2] is "<<a[2].volume( )<<endl;
return 0;
}
運行結(jié)果如下:
volume of a[0] is 1800 volume of a[1] is 5400 volume of a[2] is 8320
欄 目:C語言
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2718.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10求子數(shù)組最大和的解決方法詳解
- 01-10深入二叉樹兩個結(jié)點的最低共同父結(jié)點的詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計- 解析最少換車次數(shù)的問題詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-用棧實現(xiàn)表達式求值的方法詳解
- 01-10HDOJ 1443 約瑟夫環(huán)的最新應(yīng)用分析詳解
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實現(xiàn)全排列算法的方法詳解
- 01-10如何查看進程實際的內(nèi)存占用情況詳解
- 01-10深入Main函數(shù)中的參數(shù)argc,argv的使用詳解


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10C#中split用法實例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-11ajax實現(xiàn)頁面的局部加載
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改


