[GeekBand][C++面向?qū)ο蟾呒壘幊?下)]第四周筆記

第四周內(nèi)容比較的散,大綱如下

  1. Conversion Function
  2. non-explicit one argument constructor
  3. pointer-like classes
  4. Function-like classes
  5. namespace經(jīng)驗談
  6. class template
  7. Function Template
  8. Member Template
  9. specialization
  10. 模板偏特化
  11. 模板模板參數(shù)
  12. 關(guān)于C++標準庫
  13. 三個主題
  14. Reference
  15. 復(fù)合&繼承關(guān)系下的構(gòu)造和析構(gòu)

第四周的內(nèi)容也是相對零零散散,有虛函數(shù)指針vptr,虛函數(shù)表vtbl的,有this指針,有動態(tài)綁定Dynamic Binding。后邊還講到了成員函數(shù)。能寫多少寫多少吧。

  1. Conversion Function
Operator 類型名(){轉(zhuǎn)換語句}

比如這個例子:

#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;
}

轉(zhuǎn)換函數(shù)在函數(shù)名前面不能指定函數(shù)類型,函數(shù)也沒有參數(shù),至于是否要加const,根據(jù)轉(zhuǎn)換后的結(jié)果來判定,一般都會加上const。在使用過程中,不必顯示地調(diào)用類型轉(zhuǎn)換函數(shù),它往往是自動被調(diào)用的,即隱式調(diào)用。

23轉(zhuǎn)換構(gòu)造函數(shù):一個參數(shù)的構(gòu)造函數(shù)(或者除了第一個參數(shù)外其余參數(shù)都有默認值的多參構(gòu)造函數(shù))。

它有兩個作用:一是構(gòu)造器,二是默認且隱式的類型轉(zhuǎn)換操作符。

  1. 關(guān)鍵字explicit:

Explicit用于防止隱式轉(zhuǎn)換的,普通的構(gòu)造函數(shù)能過被隱式調(diào)用,而explicit構(gòu)造函數(shù)只能被顯示調(diào)用。

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)//重載<<運算符
{
    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;          //因為引用傳遞,所以會再調(diào)用一次non-explicit ctor
    return 0;
}

  1. shared_ptr是一種智能指針(smart point),它會記錄有多少個shared_ptr共享一個對象。當最后一個指向?qū)ο蟮闹羔槺讳N毀,這個對象就會被自動刪除。
**shared_ptr<int> sp(new int(10));                //一個指向整數(shù)的shared_ptr    
assert(sp.unique());                            //現(xiàn)在shared_ptr是指針的唯一持有者     
shared_ptr<int> sp2 = sp;                       //第二個shared_ptr,拷貝構(gòu)造函數(shù)     
assert(sp == sp2 && sp.use_count() == 2);       //兩個shared_ptr相等,指向同一個對象,引用計數(shù)為2    
*sp2 = 100;                                     //使用解引用操作符修改被指對象    
assert(*sp == 100);                             //另一個shared_ptr也同時被修改     
sp.reset();                                     //停止shared_ptr的使用    
assert(!sp);                                    //sp不再持有任何指針(空指針) 
**

網(wǎng)上的例子。

  1. 迭代器(iterator)

迭代器提供對一個容器中的對象的訪問方法,并定義了容器中對象的范圍。迭代器就如同一個指針。

  1. typename
    這周課侯老師講了在泛型編程中typename和class具體有無區(qū)別。侯老師也講了,在模板聲明里是完全沒用區(qū)別的。侯老師也提到了在模板里面的使用是有些微的區(qū)別的。但是限于篇幅與時間的限制,侯老師并沒有深入討論,所以在本筆記中,我們會討論typename與class的區(qū)別。
    比如我們有一個模板函數(shù),該函數(shù)可以打印容器內(nèi)的所有元素。如下圖所示,即使沒有typename,函數(shù)也能運行。

可是,如果我們寫一個自己的容器類,不但有const_iterator這一迭代器類型,還有一個靜態(tài)變量也叫const_iterator。這時候編譯器就會會出現(xiàn)解析錯誤了。因為我們知道,靜變量可以通過使用類名::變量名調(diào)用的。所以T::const_iterator不但是一個類型名還是一個變量名,這時候就要加入typename了。

  1. 范圍for語句

C++11新引入了一種更簡單的for語句,用于遍歷容器或其它序列的所有元素。

語法結(jié)構(gòu):

for(declaration : expression){

         ……

}

expression為要遍歷的容器

declaration為變量類型,用于存放容器中的元素,若是不清楚容器中的元素類型,可以使用auto類型說明符。

例如:

vector<int> v={0,1,2,3,4,5,6,7,8,9};

for(auto r:v)

{

         cout<<r<<endl;

}

在上面的代碼中提到了auto,它是類型說明符。

在編程時,常常需要把表達是的值賦值給變量,這就要求在聲明變量的時候清楚地知道表達式的類型,然而,往往做不到這一點,所以引入了auto類型說明符,它讓編譯器通過初始值來推算變量的類型。所以,auto定義的變量一定要有初始值。

6.[GeekBand][C++面向?qū)ο蟾呒壘幊?下)]第四周作業(yè)
作業(yè)解答在這里

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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