C++標準程序庫

openkk 12年前發布 | 17K 次閱讀 C/C++開發 C/C++

1. 如果要把一個template中的某個標識符號指定為一種型別,就算意圖顯而易見,關鍵字typename也不可或缺,因此一般的規則是,除了以typename修飾之外,template內的任何標識符號都被視為一個值而非一個型別.

2. 類的成員函數可以是個template,但這樣的成員函數既不能是virtual也不能有缺省參數.

3. 如果程序允許我們為成員函數提供不同的template型別,就可以放寬”必須精確吻合”這條規則:只要型別可被賦值,就可以被當做上述成員模板函數的參數.

4. 通過explicit,我們可以禁止”單參數構造函數”,被用于自動類型轉換.其中有對應的一個詞implicit.這個詞不是C++關鍵字(因為C++ 默認的是隱式轉換的).這里這總結類似的關鍵字: volatile.使用這個關鍵字以后,優化器在用到這個變量時必須每次都小心的重新讀取這個變量的值,而不是使用保存在寄存器中的備份.

5. auto_ptr中擁有權的轉移情況:

       ◆ 某函數是數據的終點.

       Voidskin(std::auto_ptr<ClassA>);

       ◆ 某函數是數據的起點

       此外,不能以by reference方式傳遞auto_ptr.(無法預知擁有權是否被轉交)

就特性而言,constauto_ptr類似于常數指針(T*const p).而非指向常數d的指針.(const T* p)

如果auto_ptr在整個生命期內都不必改變其所指對象的擁有權,就可以使用const auto_ptr

       const std::auto_ptr<int> p(new int(42));

         std::auto_ptr<int> q(new int( -11 ));

 

         *p = *q;//此時只是q指向了新的地址.所有權并沒有通過q轉移.

6. const 成員函數.其對象的成員不能改變.

因此不難得出以下結論:

◆const 成員函數即可以供const對象調用,也能供非const對象調用,此時const不能改變非const對象的成員

◆ const 對象不能調用非const  成員函數(因為非const對象可能會改變const對象)

◆非const函數不能調用const函數,反之可行

Mutable關鍵字:在const成員函數中也能改變mutable修飾的變量

7.  前置式遞增(++pos)與后置遞增相比,前者效率高.因為需要額外的臨時對象.所以,在一般情況下使用前置

8. 在使用set和map時,要注意排序問題.(關聯容器)它們的實現是以樹作為基本結構來存儲.

9. 三類插入迭代器:

       ◆ back inserter:利用push_back操作向容器插入.適合的容器:vector,deque,list

       ◆ front insert:利用push_front操作向容器插入.適合的容器:deque,list.(相當于鏈表前插)

       ◆ general insert:向第二個參數的位置前插入新的元素.

Inserter(contain,contain.begin()) 相當于front_insert

Inserter(contain,contain.end()) 相當于back_insert

10. 更易型算法(remove,resort,modify)不能作用于關聯式容器,因此時會改變某位置上的”值”(指鍵值).另外在選用算法的同時,首先應當確定是否可以利用容器的成員函數來代替.

11. 如果要把一個template中的某個標示符指定為一種類型,就算意圖顯而易見,關鍵字typename也不可或缺,因此C++的一般規則是,處理以type修飾之外,template內的任何標示符都被視為一個值,而非一個型別.

舉例:

class A

{

public:

         typedef  int SubType;

private:

         intvalue;

};

 

template<class T>

class MyClass{

         typedef T::SubType * ptr;

// typedef  typename T::SubType * ptr;

};

 

int main()

{

         MyClass<A> my_cls;

}

編譯器(vs2010)報錯: error C2143: 語法錯誤 : 缺少“;”(在“*”的前面).

編譯器好像并不認識SubType.這就是上面所說的把其當做為一個值,而非類型.加上typename就ok了.

11. STL容器元素必須滿足的三個基本要求:

         ◆ 必須可透過copy構造函數進行復制.

         ◆ 必須可以透過assignment操作符完成賦值動作.

         ◆ 必須可以透過析構函數完成銷毀動作.

解釋一點:我們平日里經常會寫一個類的容器,但是,類里面沒有看到什么copy,assignment什么的.為什么程序還能正常運行?

         舉例:

#include <iostream>

#include <set>

using namespace std;

class A

{

public:

         A(intiVlaue ):m_iValue( iVlaue ){}

        

private:

         intm_iValue;

};

int main()

{

         set<A> coll;

         system("pause");

         return0;

}

關鍵在于編譯器會在這種情況下幫我們合成自己的賦值和復制操作.

         其他的需要滿足特殊情況的條件:

◆  對順序容器,元素的默認構造函數必須可用

◆  對于某些特殊動作,必須定義operator==以執行相等的測試.

◆  在關聯容器中,元素必須定義排序準則,這里主要是定義<.

12. C++標準庫對STL做出如下保證:

         ◆ 所有以節點來實現基礎的容器(list,set,multiset,map,multimap),如果及誒單構造失敗,容器保持不變.移除節點的容器保持不會失敗.然而如果是對關聯式容器插入多個元素,為保證已序性,失敗時無法完全恢復原狀.對插入單一元素操作,支持要么成功,要么原先的容器不受任何影響.此外,所有擦除操作(無論數量多少)肯定成功.

         對list,就算插入多個元素,也屬于安全操作,實際上,處理remove,remove_if,merge,sort,unique之外,要么成功,要么不受任何影響.

         ◆ 所有以array為構造基礎的容器如vector,deque安插元素如果失敗,都無法做到完全恢復.如果元素的型別保證拷貝動作不拋異常,則所有加諸于改元素身上的操作都能夠保證要么成功,要么就毫無影響.

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!