13周的C++課程轉眼就學完了5周,C++的標準基本上已經覆蓋到了。再加上coding了上百行,總算是對C++有了一個基本的瞭解。接下來的學習會是關於STL的,因此在此對目前所學作一個小的總結。ios
the devil is in the detail, 這是我最大最大的體會。由其是對於這種稱之爲標準的內容而言。更是如此。c++
這三個概念是不少編程語言裏面共有的,爲了實現c++的高效率,這3板斧更是被髮揮的淋漓盡致。總結一下,能夠分爲兩種狀況:【傳】【返回】。編程
【傳】賦值的意思就是對變量進行復制 fun(int a), fun(5)。 matlab 裏所有都是這樣的調用,matlab 並不能傳引用。這樣作的好處是函數不會修改傳入值,壞處是須要對傳入的參數進行復制,若是參數很大(e10的點雲),那麼複製會有很大開銷。編程語言
【傳】引用的意思是將變量的引用傳入,好比 fun(int & a) , int b; fun(b)。這樣的作法能夠在函數中改變b的值。好處是直接傳了地址,不須要複製開銷,壞處是不利於變量保護。ide
【傳】指針和傳引用相似,通常狀況下,指針是一種很醜的參數,可是有的時候又不得不以指針做爲參數。好比點雲,每每點雲的規模是動態的,內存也是動態分配的,因此不少點雲處理函數的參數都是PointCloud<PointXYZ>::ptr,傳指針是會改變指針所指向的內容的。函數
【返回】值的意思是函數返回一個值,每每是 a = fun(b),被返回的值只能作右值。學習
【返回】引用的意思是返回一個變量,這個變量能夠有值,也能夠未被初始化。它是能夠做爲左值的,好比 a.getobj() = createobj(A). 或者 ostream & operator <<(ostream & o){return o; } cout<<MY_OBJ<<endl; this
【返回】指針,返回一個指針也是無奈之舉,好比輸入的是一個點雲,返回它的分割子集。spa
總而言之,返回引用多半是爲了作左值,返回指多半是由於有開銷上的顧慮。設計
const 有三種用法,分別是和數結合,和指針結合,和函數結合。
【和數結合】和數結合的狀況很是單純,意思就是這個變量不能改了。 int c, const int a =5; const int & b = c; 這樣的狀況下a = 1, b= 1都會報錯,若是想要b = 1,能夠令c = 1;
【和指針結合】和指針結合的狀況有點點複雜,分兩種 const int * p = & c; 表示常int,這是意思是c的值不能經過p 來修改,和上面的常引用是同樣的意思!! int const *p = & c 則表示常*p,意思就是p不能指向其餘數據。
【和函數結合】和函數結合要更復雜那麼一點點。分兩種狀況,fun(const int & a),表示a 不能被修改。fun(int a) const{},const 修飾{}——常成員函數,表示成員函數不容許修改爲員變量。常對象只能調用這種常成員函數。
構造與析構是面向對象的路子。主要是構造函數有一點複雜,分缺省構造,普通構造,拷貝構造。
【缺省構造】若是咱們不寫構造函數,那麼會自動生成缺省構造函數。可是一旦寫了,那麼就沒有缺省構造函數了。若是你想要沒參數的構造函數,要麼用缺省值假裝,要麼本身寫上 myclass(){}。建議後者,有時候不記得搞了缺省值會出事的。
【普通構造】構造函數的做用是初始化成員變量,若是成員變量是私有的,那極可能只有這麼一次機會初始化。
【拷貝構造】拷貝構造是最囉嗦的,它有兩種調用形式:一、myclass b ; myclass a(b); 二、myclass a = b。 第二種看似用了操做符 = ,實際不是的,它調了拷貝構造函數,而不是操做符重載。若是你重載了=,最好別有二義性。
【析構函數】析構函數最重要的是,若是用new 申請了變量,那麼必定要在析構函數裏delete []。固然,若是用boost 的 智能指針,能夠不用手動釋放。
操做符重載仍是比較好理解的,記好一個細節,左值要返回引用。
繼承是 is 的操做,若是一個類繼承了其夫類,那麼子類的對象,在內存裏會有父類的全部成員變量!而且自動得到父類全部的成員函數。不過得到的成員函數只能操做內存裏父類的那些成員變量了。
設計繼承最重要的是子類必須得到父類全部的性質。若是父類有一個行爲是子類不須要的,那麼就算設計的很差了。
子類中比較有難度的是構造函數的設計,由於要對內存裏父類的那些成員變量賦值,因此其構造函數要寫成以下:son(int a,int b,int c):father(a,b),c_(c){}。直接用父類的類名,來完成成員變量的賦值。一個簡單的繼承例子以下:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 using namespace std; 5 6 class MyString:public string 7 { 8 public: 9 MyString(const MyString & s):string(s){}; 10 MyString(const string & s):string(s){}; 11 MyString(const char * s):string(s){}; 12 MyString(){}; 13 14 MyString operator()(int start_index,int length){ 15 16 MyString substr = this->substr(start_index,length); 17 return substr; 18 19 } 20 21 ~MyString(){}; 22 }; 23 24 25 26 int CompareString( const void * e1, const void * e2) { 27 MyString * s1 = (MyString * ) e1; 28 MyString * s2 = (MyString * ) e2; 29 if( *s1 < *s2 ) return -1; 30 else if( *s1 == *s2 ) return 0; 31 else if( *s1 > *s2 ) return 1; 32 } 33 34 int main() { 35 MyString s1("abcd-"),s2,s3("efgh-"),s4(s1); 36 MyString SArray[4] = {"big","me","about","take"}; 37 cout << "1. " << s1 << s2 << s3<< s4<< endl; 38 s4 = s3; s3 = s1 + s3; 39 cout << "2. " << s1 << endl; 40 cout << "3. " << s2 << endl; 41 cout << "4. " << s3 << endl; 42 cout << "5. " << s4 << endl; 43 cout << "6. " << s1[2] << endl; 44 s2 = s1; s1 = "ijkl-"; 45 s1[2] = 'A' ; 46 cout << "7. " << s2 << endl; 47 cout << "8. " << s1 << endl; 48 s1 += "mnop"; 49 cout << "9. " << s1 << endl; 50 s4 = "qrst-" + s2; 51 cout << "10. " << s4 << endl; 52 s1 = s2 + s4 + " uvw " + "xyz"; 53 cout << "11. " << s1 << endl; 54 qsort(SArray,4,sizeof(MyString), CompareString); 55 for( int i = 0;i < 4;++i ) 56 cout << SArray[i] << endl; 57 //輸出s1從下標0開始長度爲4的子串 58 cout << s1(0,4) << endl; 59 //輸出s1從下標爲5開始長度爲10的子串 60 cout << s1(5,10) << endl; 61 return 0; 62 }
這裏,MyString 雖然沒說,可是得到了string全部的操做符重載(=,+....)還有全部的函數(substr)。惟一須要好好設計的就是構造函數。