第四周內(nèi)容比較的散,大綱如下
- Conversion Function
- non-explicit one argument constructor
- pointer-like classes
- Function-like classes
- namespace經(jīng)驗(yàn)談
- class template
- Function Template
- Member Template
- specialization
- 模板偏特化
- 模板模板參數(shù)
- 關(guān)于C++標(biāo)準(zhǔn)庫(kù)
- 三個(gè)主題
- Reference
- 復(fù)合&繼承關(guān)系下的構(gòu)造和析構(gòu)
第四周的內(nèi)容也是相對(duì)零零散散,有虛函數(shù)指針vptr,虛函數(shù)表vtbl的,有this指針,有動(dòng)態(tài)綁定Dynamic Binding。后邊還講到了成員函數(shù)。能寫多少寫多少吧。
- Conversion Function
Operator 類型名(){轉(zhuǎn)換語(yǔ)句}
比如這個(gè)例子:
#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é)果來判定,一般都會(huì)加上const。在使用過程中,不必顯示地調(diào)用類型轉(zhuǎn)換函數(shù),它往往是自動(dòng)被調(diào)用的,即隱式調(diào)用。
23轉(zhuǎn)換構(gòu)造函數(shù):一個(gè)參數(shù)的構(gòu)造函數(shù)(或者除了第一個(gè)參數(shù)外其余參數(shù)都有默認(rèn)值的多參構(gòu)造函數(shù))。
它有兩個(gè)作用:一是構(gòu)造器,二是默認(rèn)且隱式的類型轉(zhuǎn)換操作符。
- 關(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)//重載<<運(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;
}
- shared_ptr是一種智能指針(smart point),它會(huì)記錄有多少個(gè)shared_ptr共享一個(gè)對(duì)象。當(dāng)最后一個(gè)指向?qū)ο蟮闹羔槺讳N毀,這個(gè)對(duì)象就會(huì)被自動(dòng)刪除。
**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è)對(duì)象,引用計(jì)數(shù)為2
*sp2 = 100; //使用解引用操作符修改被指對(duì)象
assert(*sp == 100); //另一個(gè)shared_ptr也同時(shí)被修改
sp.reset(); //停止shared_ptr的使用
assert(!sp); //sp不再持有任何指針(空指針)
**
網(wǎng)上的例子。
- 迭代器(iterator)
迭代器提供對(duì)一個(gè)容器中的對(duì)象的訪問方法,并定義了容器中對(duì)象的范圍。迭代器就如同一個(gè)指針。
- typename
這周課侯老師講了在泛型編程中typename和class具體有無區(qū)別。侯老師也講了,在模板聲明里是完全沒用區(qū)別的。侯老師也提到了在模板里面的使用是有些微的區(qū)別的。但是限于篇幅與時(shí)間的限制,侯老師并沒有深入討論,所以在本筆記中,我們會(huì)討論typename與class的區(qū)別。
比如我們有一個(gè)模板函數(shù),該函數(shù)可以打印容器內(nèi)的所有元素。如下圖所示,即使沒有typename,函數(shù)也能運(yùn)行。
可是,如果我們寫一個(gè)自己的容器類,不但有const_iterator這一迭代器類型,還有一個(gè)靜態(tài)變量也叫const_iterator。這時(shí)候編譯器就會(huì)會(huì)出現(xiàn)解析錯(cuò)誤了。因?yàn)槲覀冎溃o變量可以通過使用類名::變量名調(diào)用的。所以T::const_iterator不但是一個(gè)類型名還是一個(gè)變量名,這時(shí)候就要加入typename了。
- 范圍for語(yǔ)句
C++11新引入了一種更簡(jiǎn)單的for語(yǔ)句,用于遍歷容器或其它序列的所有元素。
語(yǔ)法結(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,它是類型說明符。
在編程時(shí),常常需要把表達(dá)是的值賦值給變量,這就要求在聲明變量的時(shí)候清楚地知道表達(dá)式的類型,然而,往往做不到這一點(diǎn),所以引入了auto類型說明符,它讓編譯器通過初始值來推算變量的類型。所以,auto定義的變量一定要有初始值。
6.[GeekBand][C++面向?qū)ο蟾呒?jí)編程(下)]第四周作業(yè)
作業(yè)解答在這里