亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++成員函數與非成員函數的抉擇

2020-02-24 14:32:44
字體:
來源:轉載
供稿:網友

武林技術小編為了方便各位小伙伴學習C++,為此在這里給大家整理了一批資料,供大家交流學習,下面就跟隨武林技術頻道的編輯一起來看看C++成員函數與非成員函數的抉擇。

1.盡量用類的非成員函數以及友元函數替換類的成員函數 例如一個類來模擬人People

?

?

?

?


1 class People{
2 public:
3 ...
4 void Getup( );
5 void Washing( );
6 void eating( );
7 ...
8 }


其實上面三個動作是早上“起床”、“洗簌”、“吃飯”三個常見的動作,如果現在用一個函數來表示使用成員函數即為

?

?

?


1 class People
2 {
3 ...
4 void morningAction( )
5 {
6 Getup( );
7 Washing( );
8 eating( );
9 }
10 }


如果寫一個非成員函數即為

?

?

?


1 void moringAction(People& p)
2 {
3 p.Getup( );
4 p.Washing( );
5 p.eating( );
6 }


那么是選擇類的成員函數還是類的非成員函數呢?

面向對象則要求是,將操作數據的函數與數據放在一起。但這不意味著要選擇成員函數。從封裝的角度看,成員函數的moringAction封裝性比非成員函數要低。如果某些東西被封裝,它就不再可見。越多東西被封裝,越少人可以看到它。所以使用非成員函數的類,封裝性較低。而越少人看到它,我們就有越大彈性去變化它,因為我們的改變僅僅直接影響看到改變的那些人事物。因此,越多東西被封裝,改變哪些東西能力越大。

在考慮對象內的數據。越少的代碼可以看到數據(訪問它),越多的數據可以被封裝,而我們也就越能自由改變對象數據。現在如果一個成員函數、非成員函數都能提供相同的機能,我們選擇非成員函數。

在說下面內容之前我們先談談C++中的類型轉換分顯示類型轉換和隱式類型轉換。

2.顯示類型轉換

C++有顯示類型轉換操作符分別為:static_cast,const_cast,dynamic_cast和reinterpret_cast


2.1static_cast
轉換功能與C風格類型轉換一樣,含義也一樣。通過使用static_cast可以使沒有繼承關系的類型進行轉換。但是要注意不能將內置類型轉化為自定義類型,或者將自定義類型轉化為內置類型,并且不能將cosnt類型去掉,但能將non-cosnt類型轉換為const類型。例如:
char a='a';

int b=static_cast<int>(a);
兩個類型之間的轉換,其實也是要自己實現支持,原理和內置類型之間轉換相似。

?

?

?


1 #include <iostream>
2 class Car;
3
4 class People
5 {
6 public:
7 People(int a,int h)
8 :age(a),height(h)
9 {}
10
11 inline int getAge() const
12 {
13 return age;
14 }
15
16 inline int getHeight() const
17 {
18 return height;
19 }
20
21 People & operator=(const Car& c);
22 private:
23 int age;
24 int height;
25 };
26
27 class Car
28 {
29 public:
30 Car(double c, double w)
31 :cost(c),weight(w)
32 {}
33
34 inline double getCost() const
35 {
36 return cost;
37 }
38
39 inline double getWeight() const
40 {
41 return weight;
42 }
43
44 Car & operator=(const People& c);
45 private:
46 double cost;
47 double weight;
48 };
49
50 People & People::operator=(const Car& c)
51 {
52 age = static_cast<int>(c.getCost());
53 height = static_cast<int>(c.getWeight());
54 return *this;
55 }
56
57 Car & Car::operator=(const People& c)
58 {
59 cost = static_cast<double>(c.getAge());
60 weight = static_cast<double>(c.getHeight());
61 return *this;
62 }
63
64 int main(int argc,char * argv[])
65 {
66 Car c(1000.87,287.65);
67 People p(20,66);
68 People p2(0,0);
69 Car c2(0.00,0.00);
70 p2=c;
71 c2=p;
72 std::cout<< "car'info: cost is " << c2.getCost() << ". weight is " << c2.getWeight() <<std::endl;
73 std::cout<< "people'info: age is " << p2.getAge() <<". height is " << p2.getHeight() <<std::endl;
74 return 0;
75 }


運行結果為
car'info: cost is 20. weight is 66
people'info: age is 1000. height is 287

2.2const_cast
主要用來去掉const和volatileness屬性,大多數情況下是用來去掉const限制。


2.3dynamic_cast
它用于安全地沿著繼承關系向下進行類型轉換。一般使用dynamic_cast把指向基類指針或者引用轉換成其派生類的指針或者引用,并且當轉換失敗時候,會返回空指針。


2.4reinterprit_cast
該轉換最普通用途就是在函數指針類型之間進行轉換。

?

?

?


1 typedef void (*fun) ( ) //一個指向空函數的指針
2 fun funArray[10]; //含有10個函數指針的數據。
3 int function( ); //一個返回值為int類型函數
4 funArray[0] = &function( ) //錯誤!類型不匹配
5 funArray[0] = reinterpret_cast<fun>(&function); //ok注意轉換函數指針的代碼是不可移植的。


一般應該避免去轉換函數指針類型。

3.使用非成員函數可以發生隱式轉換
C++是支持隱式類型轉換的,例如在做運算的時候,或者傳遞參數給函數的時候常常會發生隱式類型轉換。
假設你設計一個class用來表現有理數。其實令類支持隱式類型轉換是一個槽糕的決定。當然在建立數值類型時就是例外。下面定義一個有理數類型:

?

?

?


1 class Rational {
2 public:
3 Rational( int numerator = 0,int denominator =1 );
4 int numerator( ) const;
5 int denominator ( ) const ;
6 private:
7 ...
8 }


有理數類型想當然支持算數運算,但是不確定是否聲明為成員函數或非成員函數或者是友元函數來實現它們。

首先是考慮成員函數寫法:

?

?

?


1 class Rational {
2 public:
3 ...
4 const Rational operator* (const Rational& rhs) const;
5 ...
6 }
7 Rational testOne(1,4);
8 Rational testTwo(1,1);
9 //做算術運算
10 Rational result = testOne * testTwo;
11 //與常量做運算
12 result = testOne * 2; //ok
13 //乘法滿足交換定律
14 result = 2 * testOne //error!!


那么為什么將常量提前就錯誤了呢?這里我們換一種寫法

?

?

?


1 result = testOne.operator*(2); //ok
2 result =2.operator*(oneHalf); //error


這里發生了什么?其實在第一行式子里發生了所謂隱式類型轉換。哪里發生了隱式類型轉換呢?看上面的代碼operator*函數參數是const Rational類型,而2是一個cosnt int類型,。編譯器發現有non-explicit型的單參數類為int類型的構造函數,可以造出Rational類型。所以編譯器那樣做了,發生了隱式類型轉換。所以第一個式子可以正常運行,但是第二個是沒有將Rational類型轉換為int類型的。
設計出上面兩個式子正常運行才算合理的運行。

?

?

?


1 class Rational{
2 ...
3 };
4 const Rational operator*(const Rational & lhs, const Rational & rhs)
5 {
6 return Rational(lhs.numerator() * rhs.numerator(),lhs.denominator() * rhs.denominator() );
7 }
8 Rational testOne(1, 4);
9 Rational result;
10 result = oneFourth *2;
11 result = 2 * oneFourth; 通過
12 }


按上面代碼設計成非成員函數,那么在調用int類型整數的時候會發生隱式類型轉換。
operaotr* 是否應該稱為Rational class的一個友元函數呢?對本例子而言,完全沒有必要。

如果你需要為某個函數所有參數進行類型轉換,那么這個函數必須是個非成員函數。

4.謹慎使用隱式類型轉換
我們對一些類型隱式轉換無能為力,因為它們是語言本身的特性。不過當編寫自定義類時,我們可以選擇是否提供函數讓編譯器進行隱式類型轉換。
有兩種函數允許編譯器進行隱式類型轉換:單參數構造函數與隱式類型轉換運算符。

?

?

?


1 public Name{
2 public:
3 Name(const string& s); //轉換string到Name
4
5 ...
6 };
7
8 class Rational { //有理數類
9 public:
10 //轉換從int到有理數類
11 Rational(int numerator=0,int denominatior =1);
12 ...
13 }


C++是支持隱式類型轉換的,例如在做運算的時候,或者傳遞參數給函數的時候常常會發生隱式類型轉換。有兩種函數允許編譯器進行隱式轉換。單參數構造函數和隱式類型轉換運算符。

也許前面說道了一些隱式類型轉換帶來的方便之處,下面說說一些麻煩之處。

?

?

?


1 template<class T>
2 class Array{
3 Array(int lowBound,int highBound);
4 Array(int size);
5 T& operator[](int index);
6 ...
7 };
8 bool oerpator==(const Array<int>& lhs,const Array<int>& rhs);
9 Array<int> a(10);
10 Array<int> b(10);
11 ...
12 for(int i=0;i < 10; ++i)
13 if(a == b[i]) {
14 ... }
15 else
16 {
17 ...
18 }


如果這里不小心將數組a的下標忘記寫了,這里編譯器應該報出警告信息,但是其實是沒有的。因為編譯器將a看成Array<int>類型,b為 int,根據上面的經驗,編譯器看到一個non-explicit單參數構造函數其參數類型為int,而且operator需要一個Array<int>類型,那么編譯器就這樣做了,發生了隱式類型轉換。相信如果真的發生這樣,會很麻煩。
怎么樣避免呢?將構造函數聲明為explicit。避免隱式類型轉換。更多精彩內容,盡在https://js.Vevb.com。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美中文在线观看| 欧美老女人性视频| 国产一区二区三区在线看| 亚洲精品99999| 亚洲视频欧美视频| 色播久久人人爽人人爽人人片视av| 久久久精品国产| 亚洲精品美女在线| 亚洲国产91精品在线观看| 亚洲精品日韩久久久| 日韩在线观看免费高清完整版| 亚洲成人av片在线观看| 91久久久久久久| 日韩有码在线电影| 日韩av中文字幕在线免费观看| 日韩中文字幕av| 91香蕉嫩草影院入口| 国产精品欧美久久久| 精品亚洲国产视频| 精品国产鲁一鲁一区二区张丽| 欧美影院成年免费版| 亚洲欧美日韩一区二区三区在线| 成人在线视频网站| 国产精品久久综合av爱欲tv| 久久久精品欧美| 国产成人在线一区| 欧美性极品xxxx做受| 亚洲一区亚洲二区亚洲三区| 91香蕉国产在线观看| 日韩精品久久久久久福利| 日韩在线观看免费| 国产欧美日韩中文字幕| 精品视频在线播放免| 国产精品自产拍在线观| 81精品国产乱码久久久久久| 亚洲视频在线免费观看| 日韩亚洲欧美中文高清在线| 欧美一区二区大胆人体摄影专业网站| 欧美成人精品在线视频| 97视频在线观看视频免费视频| 激情成人在线视频| 亚洲一区二区日本| 欧美电影在线观看高清| 成人欧美一区二区三区在线| 亚洲一区二区三区成人在线视频精品| 欧美性生活大片免费观看网址| 成人欧美一区二区三区在线| 欧美成人剧情片在线观看| 欧美日韩免费在线| 精品性高朝久久久久久久| 国产精品美乳在线观看| 欧美日韩xxxxx| 亚洲国产中文字幕在线观看| 欧美精品一本久久男人的天堂| 欧美xxxx综合视频| 亚洲欧美在线免费| 久久久国产影院| 精品视频—区二区三区免费| 国产精品va在线播放| 欧美日韩亚洲视频| 97精品在线视频| 亚洲欧美色图片| 国产一区二区三区四区福利| 有码中文亚洲精品| 亚洲精品99久久久久| 亚洲999一在线观看www| zzjj国产精品一区二区| 日韩中文字幕免费视频| 精品电影在线观看| 欧美在线亚洲一区| 欧美高清视频一区二区| 欧美多人爱爱视频网站| 国产精品69久久久久| 国产福利成人在线| 国产精品一区二区性色av| 4438全国亚洲精品在线观看视频| 久久久女人电视剧免费播放下载| 亚洲第一在线视频| 欧美性精品220| 成人精品一区二区三区| 日韩中文字幕av| 一区二区三区动漫| 久久久999精品视频| 欧美黑人国产人伦爽爽爽| 欧美亚洲在线观看| 日韩a**站在线观看| 伊人久久久久久久久久久| 久久伊人91精品综合网站| 国产精品免费看久久久香蕉| 国产精品国语对白| 午夜美女久久久久爽久久| 最近的2019中文字幕免费一页| 日韩高清免费在线| 91系列在线观看| 久久久91精品| 久久躁狠狠躁夜夜爽| 在线视频欧美日韩精品| 欧美成人亚洲成人日韩成人| 亚洲成av人乱码色午夜| 国产精品永久免费在线| 国产一区二区三区欧美| 欧美精品做受xxx性少妇| 91天堂在线视频| 国产精品看片资源| 欧美日韩国产一区二区三区| 97福利一区二区| 欧美丰满少妇xxxxx| 国产在线精品播放| 欧美洲成人男女午夜视频| 不卡在线观看电视剧完整版| 亚洲最新在线视频| 国产精品成人观看视频国产奇米| 久久视频在线看| 欧美成人sm免费视频| 亚洲人成绝费网站色www| 国产精品1区2区在线观看| 国产欧美一区二区白浆黑人| 亚洲国产欧美在线成人app| 亚洲人免费视频| 国产精品黄色av| 久久精品久久精品亚洲人| 波霸ol色综合久久| 日韩av影片在线观看| 国产精品久久久久久久一区探花| 国产午夜一区二区| 亚洲国产成人爱av在线播放| 欧美在线影院在线视频| 色综合色综合久久综合频道88| 国产精品欧美在线| 国产日韩在线亚洲字幕中文| 亚洲视频axxx| 日韩中文字幕在线精品| 欧美日韩在线视频观看| 国产欧美日韩专区发布| 欧美制服第一页| 国产精品视频免费观看www| 久久久www成人免费精品张筱雨| 91国产在线精品| 国产情人节一区| 日韩男女性生活视频| 在线免费看av不卡| 97久久久免费福利网址| 日韩毛片中文字幕| 亚洲自拍偷拍一区| 亚洲欧美另类中文字幕| 国内偷自视频区视频综合| 日韩视频第一页| 亚洲欧美国产视频| 久久人91精品久久久久久不卡| 欧美激情一区二区三区久久久| 亚州国产精品久久久| 成人日韩av在线| 中国人与牲禽动交精品| 欧美大尺度在线观看| 成人欧美一区二区三区在线湿哒哒| 亚洲国产小视频在线观看| 久久精品视频播放| 国产在线播放不卡| 国产盗摄xxxx视频xxx69| 久久久视频精品| 国内精品久久久久| 福利微拍一区二区| 欧美日韩一区二区在线| 国产精品网红直播|