【GeekBand】C++面向?qū)ο蟾呒壘幊?第四周筆記

課堂大綱

1.Conversion Function 轉(zhuǎn)換函數(shù)
2.non-explicit-one-argument ctor 可隱式轉(zhuǎn)換單一形參構(gòu)造函數(shù)
3.explicit-one-argument ctor 非隱式轉(zhuǎn)換單一形參構(gòu)造函數(shù)
4.兩種特殊的類
4.1. pointer-like class 智能指針
4.2. pointer_like class 迭代器
4.3. function-like classes: functor 仿函數(shù)
5.模板
5.1. 類模板
5.2. 函數(shù)模板
5.3. 成員模板
5.4. 模板特化
5.5.模板模板參數(shù)
6.關(guān)于C++標(biāo)準(zhǔn)庫
7.reference 引用


注:由于本人對這部分內(nèi)容的了解不深诀浪,所以無法寫出很詳細(xì)的心得雷猪,更多的是資料的匯總晰房,引用是從網(wǎng)絡(luò)上摘取出來的,請見諒与境。

正文

1.Conversion Function 轉(zhuǎn)換函數(shù)

形式如:

#include<iostream>
using namespace std;
class Fraction
{
public:
    Fraction(int num, int den = 1) : m_numerator(num), m_denominator(den) { }
    operator double( ) const 
    { 
        cout<<"operator double( ) is called!!!"<<endl;
        return (double)(m_numerator / m_denominator); 
    }
private:
    int m_numerator; //分子
    int m_denominator; //分母
};

int main( )
{
    Fraction f(3, 5);
    double d = 4+f;   //調(diào)用operator double( ) 將f 轉(zhuǎn)換為0.6.
    return 0;
}

運(yùn)行結(jié)果:

捕獲.JPG

轉(zhuǎn)換函數(shù)的基本規(guī)則:
-轉(zhuǎn)換函數(shù)只能是成員函數(shù)簿姨,無返回值簸搞,空參數(shù)趁俊。
-不能定義到void的轉(zhuǎn)換寺擂,也不允許轉(zhuǎn)換成數(shù)組或者函數(shù)類型。
-轉(zhuǎn)換常定義為const形式垦细,原因是它并不改變數(shù)據(jù)成員的值挡逼。
來源

在設(shè)計(jì)類的時(shí)候家坎,如果覺得有必要寫轉(zhuǎn)換函數(shù)以及認(rèn)為合理的,都是可以寫成轉(zhuǎn)換函數(shù)惹骂,
用于將該類型轉(zhuǎn)換成其他類型的对粪。
本類型->其他類型

2.non-explicit-one-argument ctor 可隱式轉(zhuǎn)換單一形參構(gòu)造函數(shù)

形式如:

#include<iostream>
using namespace std;
class Fraction
{
public:
    Fraction(int num, int den = 1) : m_numerator(num), m_denominator(den)
    { 
        cout<<"non-explicit ctor is called!!!"<<endl;
    }
    Fraction operator + (const Fraction &f)  
    { 
        cout<<"operator +(...) is called!!!"<<endl;
        return Fraction(this->m_numerator+f.m_numerator, this->m_denominator+f.m_denominator);
    }
    
    int getNumerator() const {return m_numerator;}
    int getDenominator() const {return m_denominator;}
    
private:
    int m_numerator;    //分子
    int m_denominator;  //分母
};

ostream& operator<<(ostream &os, const Fraction &f)//重載<<運(yùn)算符
{
    return os<<"分子: "<<f.getNumerator()<<"分母: "<<f.getDenominator();
}

int main( )
{
    Fraction f(3, 5);        //調(diào)用non-explicit ctor
    Fraction d2 = f+4;       //調(diào)用non-explicit ctor將4轉(zhuǎn)為 Fraction(4,1)
                             //然后調(diào)用operator + 
    cout<<d2<<endl;          //因?yàn)橐脗鬟f衩侥,所以會(huì)再調(diào)用一次non-explicit ctor
    return 0;
}

運(yùn)行結(jié)果:

捕獲.JPG

那么如果轉(zhuǎn)換函數(shù)和運(yùn)算符+重載都在同一個(gè)類里面呢?按照上述的程序履羞,會(huì)發(fā)生什么問題忆首?

class Fraction
{
public:
    ...
    Fraction operator + (const Fraction &f)  
    { 
        cout<<"operator +(...) is called!!!"<<endl;
        return Fraction(this->m_numerator+f.m_numerator, this->m_denominator+f.m_denominator);
    }
    operator double( ) const 
    { 
        cout<<"operator double( ) is called!!!"<<endl;
        return (double)(m_numerator / m_denominator); 
    }
    ...
};

編譯結(jié)果:

捕獲.JPG

我個(gè)人認(rèn)為是編譯器不知道需要調(diào)用內(nèi)置+運(yùn)算還是用戶自定義的+運(yùn)算
緣由在于:
1.如果編譯器利用類中的double()來將f轉(zhuǎn)換為double型后糙及,便可以用內(nèi)置+號來作運(yùn)算浸锨;
2.但編譯器也可以將4轉(zhuǎn)換成Fraction,然后在調(diào)用用戶自定義的operator+迟郎。
但編譯器不知道用戶的真實(shí)目的是如何聪蘸,所以便報(bào)錯(cuò)了健爬。
有些時(shí)候編譯器幫助我們完成的隱式轉(zhuǎn)換會(huì)帶來錯(cuò)誤,為了解決這個(gè)問題蜕衡,我們?yōu)榇艘胍粋€(gè)關(guān)鍵字↓

3.explicit-one-argument ctor 非隱式轉(zhuǎn)換單一形參構(gòu)造函數(shù)

class Fraction
{
public:
    explicit Fraction(int num, int den = 1) : m_numerator(num), m_denominator(den) //請注意前面的關(guān)鍵字
    { 
        cout<<"non-explicit ctor is called!!!"<<endl;
    }
    Fraction operator + (const Fraction &f)  
    { 
        cout<<"operator +(...) is called!!!"<<endl;
        return Fraction(this->m_numerator+f.m_numerator, this->m_denominator+f.m_denominator);
    }
        operator double( ) const 
    { 
        cout<<"operator double( ) is called!!!"<<endl;
        return (double)(m_numerator / m_denominator); 
    }

編譯結(jié)果是:


捕獲.JPG

因?yàn)榧恿薳xplicit關(guān)鍵字后,構(gòu)造函數(shù)不會(huì)發(fā)生隱式轉(zhuǎn)換镶骗,所以double轉(zhuǎn)向Fraction時(shí)就會(huì)報(bào)錯(cuò)躲雅。

explicit 只對構(gòu)造函數(shù)起作用相赁,用來抑制隱式轉(zhuǎn)換。
來源

4.兩種特殊的類

4.1. pointer-like class 關(guān)于智能指針

template<class T>
class shared_ptr
{
public:
    T& operator* ( ) const { return *px; }
    T* operator->( ) const { return px; }

    shared_ptr(T* p) : px(p) { }
private:
    T* px;
    long* pn;
};

使用舉例:

struct Foo
{
    ......
    void method(void) {......}
};
shared_ptr<Foo> sp(new Foo);
Foo f(*sp);     //*sp則調(diào)用shared_ptr類中的*重載運(yùn)算符,返回了Foo類的一個(gè)指針?biāo)傅摹緦ο蟆?
sp->method( );  //調(diào)用shared_ptr類中的->重載運(yùn)算符绵脯,返回了一個(gè)Foo的指針。
                //->比較特別妙黍,解引用之后還能繼續(xù)傳遞下去瞧剖。

網(wǎng)上摘取一段關(guān)于shared_ptr的使用例子

**shared_ptr<int> sp(new int(10)); //一個(gè)指向整數(shù)的shared_ptr
assert(sp.unique()); //現(xiàn)在shared_ptr是指針的唯一持有者
shared_ptr<int> sp2 = sp; //第二個(gè)shared_ptr,拷貝構(gòu)造函數(shù)
assert(sp == sp2 && sp.use_count() == 2); //兩個(gè)shared_ptr相等,指向同一個(gè)對象,引用計(jì)數(shù)為2
sp2 = 100; //使用解引用操作符修改被指對象
assert(
sp == 100); //另一個(gè)shared_ptr也同時(shí)被修改
sp.reset(); //停止shared_ptr的使用
assert(!sp); //sp不再持有任何指針(空指針)
**

[來源](http://blog.csdn.net/sndaxdrs/article/details/6175701)

*注意:assert的作用是現(xiàn)計(jì)算表達(dá)式 expression 抓于,如果其值為假(即為0)毡咏,那么它先向stderr打印一條出錯(cuò)信息,然后通過調(diào)用 abort 來終止程序運(yùn)行*

個(gè)人覺得堵泽,智能指針實(shí)際上就是傳統(tǒng)普通指針的擴(kuò)展迎罗,所以究其本質(zhì)片仿,其內(nèi)部還是必須有一個(gè)普通指針砂豌,然后再拓展其功能。

####4.2. pointer_like class 迭代器
示例程序:
```C++
template<class T>
class __list_node
{
public:
    void* prev;
    void* next;
    T data;
};
template<class T, class Ref, class Ptr>
class __list_iterator
{
public:
    ...
    typedef Ptr pointer;
    typedef Ref reference;
    reference operator * ( ) const { return (*node).data; }
    pointer operator -> ( ) const { return &(operator*( )); }
    ...
};
list<Foo>::iterator ite;
...
*ite;          //獲得一個(gè)Foo object;
ite->method( );//調(diào)用Foo::method( );
               //相當(dāng)于(*ite).method( );
               //相當(dāng)于(&(*ite))->method( );

迭代器本身就是一種指針,所以當(dāng)用的時(shí)候筐摘,實(shí)際上是對該迭代器進(jìn)行解引用咖熟,相當(dāng)于讀取它所指的對象的值馍管,所以可以看到重載運(yùn)算符函數(shù)里面是返回data的。
而當(dāng)調(diào)用->的時(shí)候捌锭,可以分成operator*()被調(diào)用后,再被取值,為此相當(dāng)于是先讀取所指對象的值坎匿,然后再取地址雷激,所以返回是一個(gè)指針屎暇。
另外,迭代器和智能指針不同之處是迭代器還要重載++或者--凶异,進(jìn)行指針移動(dòng)操作剩彬。

4.3. function-like classes: functor 仿函數(shù)

被派出差矿卑,回來更~

5.模板

5.1. 類模板

5.2. 函數(shù)模板

5.3. 成員模板

5.4. 模板特化

5.5.模板模板參數(shù)

6.關(guān)于C++標(biāo)準(zhǔn)庫

7.reference 引用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喉恋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子母廷,更是在濱河造成了極大的恐慌轻黑,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琴昆,死亡現(xiàn)場離奇詭異氓鄙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)椎咧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門玖详,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勤讽,“玉大人蟋座,你說我怎么就攤上這事〗烹梗” “怎么了向臀?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诸狭。 經(jīng)常有香客問我券膀,道長君纫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任芹彬,我火速辦了婚禮蓄髓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舒帮。我一直安慰自己会喝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布玩郊。 她就那樣靜靜地躺著肢执,像睡著了一般。 火紅的嫁衣襯著肌膚如雪译红。 梳的紋絲不亂的頭發(fā)上预茄,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音侦厚,去河邊找鬼耻陕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛假夺,可吹牛的內(nèi)容都是我干的淮蜈。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼已卷,長吁一口氣:“原來是場噩夢啊……” “哼梧田!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起侧蘸,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤裁眯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后讳癌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體穿稳,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年晌坤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逢艘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骤菠,死狀恐怖它改,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情商乎,我是刑警寧澤央拖,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響鲜戒,放射性物質(zhì)發(fā)生泄漏专控。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一遏餐、第九天 我趴在偏房一處隱蔽的房頂上張望伦腐。 院中可真熱鬧,春花似錦失都、人聲如沸蔗牡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘁扼,卻和暖如春信粮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背趁啸。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工强缘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人不傅。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓旅掂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親访娶。 傳聞我的和親對象是個(gè)殘疾皇子商虐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容