日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

c 面向?qū)ο蟮木幊倘腴T篇-----類(class

 funson 2007-04-03

//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

class test
{
private:
int number;
public:
float socre;
public:
int rp()
{
return number;
}
void setnum(int a)
{
number=a;
}
};



但是大家注意到?jīng)]有,標(biāo)準(zhǔn)c中是不允許在結(jié)構(gòu)體中聲明函數(shù)的,但c++中的類可以,這一點(diǎn)就和c有了本質(zhì)的區(qū)別,很好的體現(xiàn)了c++面向?qū)ο蟮奶攸c(diǎn)!

過去的c語(yǔ)言是一種非面向?qū)ο蟮恼Z(yǔ)言

他的特性是

程序=算法+數(shù)據(jù)結(jié)構(gòu)

但c++的特性是

對(duì)象=算法+數(shù)據(jù)結(jié)構(gòu)
程序=對(duì)象+對(duì)象+對(duì)象+對(duì)象+........

所以根據(jù)這一特性,我們?cè)诙x一個(gè)自己定義的結(jié)構(gòu)體變量的時(shí)候,這個(gè)變量就應(yīng)該是叫做對(duì)象或者叫實(shí)例

例如

test a;
那么a就是test結(jié)構(gòu)的一個(gè)對(duì)象(實(shí)例)

test結(jié)構(gòu)體內(nèi)的成員可以叫做是分量,例如:

a.socre=10.1f;
那么number就是test結(jié)構(gòu)的對(duì)象a的分量(或者叫數(shù)據(jù)成員,或者叫屬性)score;

在c語(yǔ)言中結(jié)構(gòu)體中的各成員他們的默認(rèn)存儲(chǔ)控制是public 而 c++中類的默認(rèn)存儲(chǔ)控制是private,所以在類中的成員如果需要外部掉用一定要加上關(guān)鍵字public聲明成公有類型,這一特性同樣使用于類中的成員函數(shù),函數(shù)的操作方式和普通函數(shù)差別并不大

例如上面的例子中的rp()成員函數(shù),我們?nèi)绻视腥缦露x

test a;
的話,調(diào)用rp()就應(yīng)該寫成

a.rp();

成員函數(shù)的調(diào)用和普通成員變量的調(diào)用方式一致都采用.的操作符。

這一小節(jié)為了鞏固聯(lián)系我給出一個(gè)完整的例子。

如下(重要和特殊的地方都有詳細(xì)的注解):


//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

#include <iostream>
using namespace std;
class test
{
private://私有成員類外不能夠直接訪問
int number;
public://共有成員類外能夠直接訪問
float socre;
public:
int rp()
{
return number;
}
void setnum(int a)
{
number=a;
}
};

void main()
{
test a;
//a.number=10;//錯(cuò)誤的,私有成員不能外部訪問
a.socre=99.9f;
cout<<a.socre<<endl;//公有成員可以外部訪問
a.setnum(100);//通過公有成員函數(shù)setnum()間接對(duì)私有成員number進(jìn)行賦值操作
cout<<a.rp();//間接返回私有成員number的值
cin.get();
}



好了,介紹了在類內(nèi)部定義成員函數(shù)(方法)的方法,下面我們要介紹一下域區(qū)分符(::)的作用了。

下面我們來看一個(gè)例子,利用這個(gè)例子中我們要說明兩個(gè)重要問題:


//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

#include <iostream>
using namespace std;
int pp=0;
class test
{
private:
int number;
public:
float socre;
int pp;
public:
void rp();
};
void test::rp()//在外部利用域區(qū)分符定義test類的成員函數(shù)
{
::pp=11;//變量名前加域區(qū)分符給全局變量pp賦值
pp=100;//設(shè)置結(jié)構(gòu)體變量
}

void main()
{
test a;
test b;
a.rp();
cout<<pp<<endl;
cout<<a.pp<<endl;

cin.get();
}
問題1:


利用域區(qū)分符我們可以在類定義的外部設(shè)置成員函數(shù),但要注意的是,在類的內(nèi)部必須預(yù)先聲明:

void test::rp()

在函數(shù)類型的后面加上類的名稱再加上域區(qū)分符(::)再加函數(shù)名稱,利用這樣的方法我們就在類的外部建立了一個(gè)名為rp的test類大成員函數(shù)(方法),可能很多人要問,這么做有意義嗎?在類的內(nèi)部寫函數(shù)代碼不是更好?
答案是這樣的:在類的定義中,一般成員函數(shù)的規(guī)模一般都比較小,而且一些特殊的語(yǔ)句是不能夠使用的,而且一般會(huì)被自動(dòng)的設(shè)置成為inline(內(nèi)聯(lián))函數(shù),即使你沒有明確的聲明為inline,那么為什么有會(huì)被自動(dòng)設(shè)置成為inline呢?因?yàn)榇蠖鄶?shù)情況下,類的定義一般是放在頭文件中的,在編譯的時(shí)候這些函數(shù)的定義也隨之進(jìn)入頭文件,這樣就會(huì)導(dǎo)致被多次編譯,如果是inline的情況,函數(shù)定義在調(diào)用處擴(kuò)展,就避免了重復(fù)編譯的問題,而且把大量的成員函數(shù)都放在類中使用起來也十分不方便,為了避免這種情況的發(fā)生,所以c++是允許在外部定義類的成員函數(shù)(方法)的,將類定義和其它成員函數(shù)定義分開,是面向?qū)ο缶幊痰耐ǔW龇ǎ覀儼杨惖亩x在這里也就是頭文件了看作是類的外部接口,類的成員函數(shù)的定義看成是類的內(nèi)部實(shí)現(xiàn)。寫程序的時(shí)候只需要外部接口也就是頭文件即可,這一特點(diǎn)和我們使用標(biāo)準(zhǔn)庫(kù)函數(shù)的道理是一致的,因?yàn)樵陬惖亩x中,已經(jīng)包含了成員函數(shù)(方法)的聲明。

問題二

域區(qū)分符和外部全局變量和類成員變量之間的關(guān)系。

在上面的代碼中我們看到了,外部全局和類內(nèi)部都有一個(gè)叫做pp的整形變量,那么我們要區(qū)分操作他們用什么方法呢?

使用域區(qū)分符就可以做到這一點(diǎn),在上面的代碼中::pp=11;操作的就是外部的同名稱全局變量,pp=100;操作的就是類內(nèi)部的成員變量,這一點(diǎn)十分重要!

問題三

一個(gè)類的所有對(duì)象調(diào)用的都是同一段代碼,那么操作成員變量的時(shí)候計(jì)算機(jī)有是如何知道哪個(gè)成員是屬于哪個(gè)對(duì)象的呢?
這里牽扯到一個(gè)隱藏的this指針的問題,上面的代碼在調(diào)用a.rp()的的時(shí)候,系統(tǒng)自動(dòng)傳遞一了個(gè)a對(duì)象的指針給函數(shù),在內(nèi)部的時(shí)候pp=100;的時(shí)候其實(shí)就是this->pp=100;

所以你把上面的成員函數(shù)寫成如下形勢(shì)也是正確的:

void test::rp()
{
::pp=11;
this->pp=100;//this指針就是指向a對(duì)象的指針
}



類的成員函數(shù)和普通函數(shù)一樣是可以進(jìn)行重載操作的,關(guān)于重載函數(shù)前面已經(jīng)說過,這里不再說明。

給出例子仔細(xì)看:


//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

#include <iostream>
using namespace std;
class test
{
private:
int number;
public:
float socre;
int pp;
public:
void rp(int);
void rp(float);
};
void test::rp(int a)//在外部利用域區(qū)分符定義test類的成員函數(shù)
{
cout<<"調(diào)用成員函數(shù)!a:"<<a<<endl;
}
void test::rp(float a)//在外部利用域區(qū)分符定義test類的成員函數(shù)
{
cout<<"調(diào)用成員函數(shù)!a:"<<a<<endl;
}
void main()
{
test a;
a.rp(100);
a.rp(3.14f);
cin.get();
}

下面我們來看一下利用指針和利用引用間接調(diào)用類的成員函數(shù),對(duì)于對(duì)于指針和引用調(diào)用成員函數(shù)和調(diào)用普通函數(shù)差別不大,在這里也就不再重復(fù)說明了,注意看代碼,多試多練習(xí)既可。

代碼如下:


//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

#include <iostream>
using namespace std;
class test
{
private:
int number;
public:
float socre;
int pp;
public:
int rp(int);
};
int test::rp(int a)//在外部利用域區(qū)分符定義test類的成員函數(shù)
{
number=100;
return a + number;
}

void run(test *p)//利用指針調(diào)用
{
cout<<p->rp(100)<<endl;
}
void run(test &p)//利用引用
{
cout<<p.rp(200)<<endl;
}

void main()
{
test a;
run(&a);
run(a);
cin.get();
}

前面我們說過,類的成員如果不顯式的生命為public那么它默認(rèn)的就是private就是私有的,私有聲明可以保護(hù)成員不能夠被外部訪問,但在c++還有一個(gè)修飾符,它具有和private相似的性能,它就是protected修飾符。

在這里我們簡(jiǎn)單說明一下,他們?nèi)g的差別:

在類的private:節(jié)中聲明的成員(無論數(shù)據(jù)成員或是成員函數(shù))僅僅能被類的成員函數(shù)和友元訪問。
在類的protected: 節(jié)中聲明的成員(無論數(shù)據(jù)成員或是成員函數(shù))僅僅能被類的成員函數(shù),友元以及子類的成員函數(shù)和友元訪問。
在類的public:節(jié)中聲明的成員(無論數(shù)據(jù)成員或是成員函數(shù))能被任何人訪問。

由于private和protected的差別主要是體現(xiàn)在類的繼承中,現(xiàn)在的教程還沒有設(shè)計(jì)到友元和子類所以這里不做深入討論,但上面的三點(diǎn)務(wù)必記得,在以后的教程中我們會(huì)回過頭來說明的。

總的來說,類成員的保護(hù)無非是為了以下四點(diǎn)!

1.相對(duì)與普通函數(shù)和其它類的成員函數(shù)來說,保護(hù)類的數(shù)據(jù)不能夠被肆意的篡改侵犯!

2.使類對(duì)它本身的內(nèi)部數(shù)據(jù)維護(hù)負(fù)責(zé),只有類自己才能夠訪問自己的保護(hù)數(shù)據(jù)!

3.限制類的外部接口,把一個(gè)類分成公有的和受保護(hù)的兩部分,對(duì)于使用者來說它只要會(huì)用就可以,無須了解內(nèi)部完整結(jié)構(gòu),起到黑盒的效果。

4.減少類與其它代碼的關(guān)聯(lián)程,類的功能是獨(dú)立的,不需要依靠應(yīng)用程序的運(yùn)行環(huán)境,這個(gè)程序可以用它,另外一個(gè)也可以用它,使得你可以輕易的用一個(gè)類替換另一個(gè)類。


下面為了演示類成員的保護(hù)特性,我們來做一個(gè)球類游戲!

我們?cè)O(shè)計(jì)一個(gè)類,來計(jì)算球員的平均成績(jī),要求在外部不能夠隨意篡改球員的平均成績(jī)。

我們把該類命名為ballscore并且把它放到ballscore.h的有文件中!


--------------------------- ballscore.h-----------------------------

class ballscore
{
protected:
const static int gbs = 5;//好球單位得分
const static int bbs = -3;//壞球單位扣分
float gradescore;//平均成績(jī)
public:
float GetGS(float goodball,float badball)//goodball為好球數(shù)量,badball為壞求數(shù)量
{
gradescore = (goodball*gbs + badball*bbs) / (goodball + badball);
return gradescore;//返回平均成績(jī)
}
};


--------------------------------------------------------------------

主函數(shù)調(diào)用!

#include <iostream>
#include "ballscore.h"
using namespace std;

void main()
{
ballscore jeff;
cout<<jeff.GetGS(10,3);
jeff.gradescore=5.5//想篡改jeff的平均成績(jī)是錯(cuò)誤的!
cin.get();
}



在上面的代碼中頭文件和類的使用很好了體現(xiàn)了類的黑盒特性,誰(shuí)也不能夠在外部修改球員的平均成績(jī)!

類體中的有一個(gè)地方要注意

const static int gbs = 5;//好球單位得分
const static int bbs = -3;//壞球單位扣分

之所以要修飾成const static 因?yàn)閏++中類成員只有靜態(tài)整形的常量才能夠被初始化,到這里整個(gè)程序也就說完了,當(dāng)然真正大比賽不可能是這樣,只是為了說明問題就題命題而已,呵呵!
下面我們說一下關(guān)于類的作用域。

在說內(nèi)容之前我們先給出這部分內(nèi)容的一個(gè)完整代碼,看講解的是參照此一下代碼!


//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

#include <iostream>
using namespace std;
class ballscore
{
protected:
const static int gbs = 5;//好球單位得分
const static int bbs = -3;//壞球單位扣分
float gradescore;//平均成績(jī)
public:
float GetGS(float goodball,float badball)//goodball為好球數(shù)量,badball為壞求數(shù)量
{
int gradescore=0;//新定義一個(gè)和成員變量float gradescore相同名字的類成員函數(shù)局部變量
ballscore::gradescore = (goodball*gbs + badball*bbs) / (goodball + badball);//由于局部變量與類成員變量同名使用的時(shí)候必須在其前加上類名和域區(qū)分符
return ballscore::gradescore;//返回平均成績(jī)
}
};
int ballscore=0;//定義一個(gè)與類名稱相同的普通全局變量
int test;
void main()
{
class test//局部類的創(chuàng)建
{
float a;
float b;
};
test test;
::test=1;//由于局部類名隱藏了外部變量使用需加域區(qū)分符
class ballscore jeff;//由于全局變量int ballsocre和類(ballsocre)名稱相同,隱藏了類名稱,這時(shí)候定義類對(duì)象需加class前綴以區(qū)分
cout<<jeff.GetGS(10,3);
cin.get();
}




類的作用域是只指定義和相應(yīng)的成員函數(shù)定義的范圍,在該范圍內(nèi),一個(gè)類的成員函數(shù)對(duì)同一類的數(shù)據(jù)成員具有無限制的訪問權(quán)。

在類的使用中,我們經(jīng)常會(huì)碰到以下三種情況:

1.類的成員函數(shù)的局部變量隱藏了類的同名成員變量,看如對(duì)上面程序的分析。

protected:
const static int gbs = 5;
const static int bbs = -3;
float gradescore;
public:
float GetGS(float goodball,float badball)
{
int gradescore=0;
ballscore::gradescore = (goodball*gbs + badball*bbs) / (goodball + badball);
return ballscore::gradescore;
}



代碼中的int gradescore就把float gradescore給隱藏了,所以要使用成員變量float gradescore的時(shí)候必須在其之前加上類名稱和域區(qū)分符(::)。

2.在類定義外部非類型名隱藏了類型名稱的情況,看上面代碼的分析!

class ballscore
{
protected:
const static int gbs = 5;
const static int bbs = -3;
float gradescore;
public:
float GetGS(float goodball,float badball)
{
int gradescore=0;
ballscore::gradescore = (goodball*gbs + badball*bbs) / (goodball + badball);
return ballscore::gradescore;
}

};
int ballscore=0;

代碼中的全部變量int ballscore隱藏了類名稱class ballscore

所以在main中如如果要定義ballscore類的對(duì)象就要在類名稱前加上class關(guān)鍵字

class ballscore jeff;

3.類型名稱隱藏了非類型名稱,看對(duì)上面代碼的分析!

int test;
void main()
{
class test
{
float a;
float b;
};
test test;
::test=1;
class ballscore jeff;
cout<<jeff.GetGS(10,3);
cin.get();
}

在普通函數(shù)內(nèi)部定義的類叫做局部類,代碼中的test類就是一個(gè)局部類!

代碼中的test類隱藏了全局變量test如果要操作全局變量test那么就要在test前加上域區(qū)分符號(hào)(::),進(jìn)行使用!

::test=1就是對(duì)全局變量test進(jìn)行了賦值操作!

我們最后說一下名字空間!

名字空間就是指某一個(gè)名字在其中必須是唯一的作用域.

如果這個(gè)定義想不明白,可以簡(jiǎn)單的說成,在一個(gè)區(qū)域內(nèi),某一個(gè)名字在里面使用必須是唯一的,不能出現(xiàn)重復(fù)定義的情況出現(xiàn),這個(gè)區(qū)域就是名字空間!

c++規(guī)定:

1.一個(gè)名字不能同時(shí)設(shè)置為兩種不同的類型

class test
{
//...
};
typedef int test;
這個(gè)就是錯(cuò)誤的!

2.非類型名(變量名,常量名,函數(shù)名,對(duì)象名,枚舉成員)不能重名.

test a;

void a();
就是錯(cuò)誤的,因?yàn)閍是一個(gè)test類的對(duì)象,它和函數(shù)a名稱重名了!

3.類型與非類型不在同一個(gè)名字空間上,可以重名,即使在同一作用域內(nèi),但兩者同時(shí)出現(xiàn)時(shí)定義類對(duì)象的時(shí)候要加上前綴class以區(qū)分類型和非類型名!
class test
{
//.....
}

int test

class test a;//利用class前墜區(qū)分,定義了一個(gè)test類的對(duì)象a


好了,到這里關(guān)于類的知識(shí)點(diǎn)我們已經(jīng)學(xué)習(xí)完,希望大家多多練習(xí)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多