0. 首先先說作業(yè)
因?yàn)檫@次的作業(yè)看起來和第十周的課程更相近坛吁,所以把第十周看了。導(dǎo)致并沒有時(shí)間回顧第九周及之前的課程闷尿,結(jié)果就是在寫作業(yè)的時(shí)候一臉懵比,出現(xiàn)各種錯(cuò)誤。這次出現(xiàn)的錯(cuò)誤非常有啟發(fā)性匆骗,所以列在最前誉简。
0.1 錯(cuò)誤的編譯環(huán)境
更換系統(tǒng)后用的是官方的MinGW,幾次編譯都很正常瓮钥,并沒有什么問題。
但是今天在查詢代碼的時(shí)候出現(xiàn)了無法使用C++11中string的幾個(gè)數(shù)值轉(zhuǎn)換函數(shù)的問題〗拔洌現(xiàn)象就是使用to_string等函數(shù)時(shí)顯示無法解析名字锈津。
后來更換Code::Blocks才編譯正常, 懷疑是MinGW版本(5.3.0)太舊的問題性誉,查看文檔后得知Code::Blocks中用的版本是6.2.0茎杂,于是按編譯說明找到了下載地址MinGW-w64。更換編譯環(huán)境后編譯正常倾哺。
0.2 錯(cuò)誤的設(shè)計(jì)模式
昨天在編程之前并沒有仔細(xì)思考携冤,是從測試代碼和題目要求分別從輸出函數(shù)和基礎(chǔ)類兩方面推進(jìn),最后并沒有匯合曾棕,代碼微妙的錯(cuò)開了翘地。導(dǎo)致兩邊的接口完全對不上,一邊請求的是函數(shù)昧穿,而另一邊提供的是類型。沒有仔細(xì)思考會(huì)遇到的問題導(dǎo)致錯(cuò)誤的接口橙喘。
0.3 并不理解Traits的本質(zhì)
現(xiàn)在也仍然弄不清楚Traits到底是什么时鸵,一開始的感覺就是利用泛化和特化來獲得指定的struct數(shù)值。但是現(xiàn)在感覺并不是這樣厅瞎。如果沒有充分理解Traits到底是什么饰潜,那就沒有辦法靈活的運(yùn)用。這次的混亂大都產(chǎn)生于此和簸。
0.4 并不扎實(shí)的基本功
雖然老師說“勿在浮沙筑高臺(tái)”彭雾,但是短時(shí)間沒有辦法彌補(bǔ)巨大的差距。
典型的問題出現(xiàn)在對基類與子類的關(guān)系锁保,為此專門拿出書本仔細(xì)閱讀薯酝,發(fā)現(xiàn)缺少大量的相關(guān)知識(shí)半沽。
對于private中數(shù)值的繼承、對于構(gòu)造函數(shù)的繼承吴菠、對于基類函數(shù)的繼承,雖然有所了解幔托,但是完全不知道是怎么回事重挑,以及如何使用谬哀。
class Value{
public:
Value(double m = 0):mvalue(m){}
double key() const {
return mvalue;
}
protected:
double mvalue;
};
class kilometer:public Value {
public:
using Value::Value;
};
這段代碼就是以前從來沒有見過的史煎,如果沒有看書也不會(huì)想到還可以這么寫篇梭。由于對OOP認(rèn)識(shí)并不清楚恬偷,所以只能寫繼承關(guān)系袍患,但是感覺其他的可能會(huì)更好诡延。
0.5 缺少實(shí)踐經(jīng)驗(yàn)以及理解不足
對于模板的使用完全沒有概念肆良,僅僅是照貓畫虎妖滔。所以對于引用傳遞的內(nèi)容非常模糊,就會(huì)出現(xiàn)下面這種疑問:“為什么傳引用會(huì)失效陨帆?”如果寫成print(T& x)
疲牵,傳遞過來的類型T就會(huì)變成Value纲爸,導(dǎo)致Traits失效识啦。之前還有很多類似的問題颓哮,所以不僅要知道reference傳遞的內(nèi)容是什么冕茅,也要知道傳遞的類型是什么姨伤。
// 此處傳引用會(huì)失效??為什么当编?
template<typename T>
string print(T x){
string str;
int ts=x.key()*dimension<T>::scale+0.5;
str= to_string(ts); //Clion不支持to_string凌箕,為什么牵舱?芜壁?
// str.push_back(to_string(x.key()*dimension<T>::scale));
str.push_back(dimension<T>::unit);
return str;
}
之前還出現(xiàn)過這樣的問題慧妄,現(xiàn)在看來非常愚蠢剪芍,但是因?yàn)榈谝淮斡龅阶锕跃秃翢o意識(shí)。
下面這段代碼直接重載了所有的<<
谁帕,導(dǎo)致這個(gè)操作符廢了匈挖。如何避免這種情況儡循,避免過度重載贮折?這些還要再回顧一下特化等知識(shí)。
//過度重載
template<typename T>
inline
ostream& operator<<(ostream& os, const T& x)
{
return os << x.key()*dimension<T>::scale << dimension<T>::unit;
}
算法的形式
C++標(biāo)準(zhǔn)庫的算法呵扛,是什么東西今穿?
迭代器必須可以回答算法提出的所有問題蓝晒。
類型+() 直接生成臨時(shí)對象
30. 算法源代碼剖析(11個(gè)例子)
先前示例中出現(xiàn)的算法
算法 accumulate
可以傳函數(shù)芝薇,也可以傳像函數(shù)的東西
struct myclass {
int operator()(int x, int y){return x+3*y;}
} myobj;
算法 for_each
算法 replace, replace_if, replace_copy
Predicate 判斷式
算法count馋劈,count_if
算法find妓雾,find_if
算法sort
算法 rbegin rend
reverse_iterator
算法 binary_search
仿函數(shù) functors
最簡單的能夠?qū)懗鰜砣谌隨TL的
- 算術(shù)類
- 邏輯運(yùn)算類
- 相對關(guān)系類
要仿函數(shù)械姻,就必須要重載()
因?yàn)橐?-操作傳給算法楷拳,所以要用仿函數(shù)唯竹。
仿函數(shù)functors的可適配條件
沒有繼承,就說明沒有融入STL
繼承不繼承有什么差別
繼承的是binary_function
一個(gè)沒有數(shù)據(jù)的類产上,占用大小是0或者1晋涣,被繼承時(shí)谢鹊,占用大小是0。
子類會(huì) 繼承typedef
存在多種 Adapters
adapters就是換個(gè)衣服
會(huì)出現(xiàn)在三個(gè)地方:
- 迭代器適配器
- 仿函數(shù)適配器
- 容器適配器
容器適配器:stack兼耀,queue
set瘤运,multiset拯坟?
函數(shù)適配器:binder2nd
注意bind2nd是輔助函數(shù),binder2nd是對象
函數(shù)適配器:binder2nd
沒看懂巩踏,一個(gè)函數(shù)適配器需要回答那幾個(gè)問題塞琼?
typename 通知編譯器彪杉,后面是一個(gè)類型,可以編譯通過攀唯。
既要能提出問題,又能回答問題
既可以適配戒幔,又能被適配
所以要繼承unary
函數(shù)適配器:not1
用compose把一大堆a(bǔ)dapter組合在一起诗茎?
新型適配器敢订,bind Since C++11
..\include\c++\backward\backward_warning.h
binder2nd過時(shí)了,要用bind取代
std::bind 可以綁定:
- functions
- function objects
- member functions _1 必須是某個(gè)object地址
- data members _1 必須是某個(gè)object地址
_1 占位符號(hào)
using namespace std::placeholders; //add visibility _1,_2,_3,...
bind<T>醒叁,只能綁定一個(gè)把沼,綁定的是返回值
member function 其實(shí)有個(gè)參數(shù) this
可以返回函數(shù)值,也可以返回data值
迭代器適配器 reverse_iterator
rbegin() rend()
解引用時(shí)先--捆愁、】 【【
迭代器適配器:inserter
普通的copy不檢查空間是否越界
所以給iterator增加適配器
inserter 對象被賦值時(shí)調(diào)用賦值的操作符重載,從而在不更改copy代碼的前提下更改流程
x適配器:ostream_iterator
不知道該算什么適配器
delimiter 分隔符
x適配器:istream_iterator
std::istream_iterator<double> eos; // 沒有參數(shù)菩帝,空的宜雀,是一個(gè)end-of-stream iterator
為什么一創(chuàng)建就要讀取呢辐董?
第二個(gè)例子相當(dāng)于文本框郎哭?
copy不止能把確定的序列復(fù)制到目標(biāo)中去邦蜜,也可以把可++的Iterator指向的對象悼沈。