1、讓自己習慣C++

條款01:視C++爲一個語言聯邦

C++是由下述四個次語言組成:

  • C。C++支持面向過程編程,所用基礎語法完全等同於C。
  • Object-Orited C++。C++面向對象編程,級C with Classed。
  • Template C++。C++泛型編程(generic programming)部分。
  • STL。STL是C++的一個template程序庫,其中包含了大量的容器、迭代器、算法。

因此,C++高效編程守則視狀態而變化,取決於使用C++的哪一個次語言。

條款02:儘量以const, enum, inline替換#define

  1. #define是預處理器命令,對編譯器不可見。因此#define定義的符號,編譯器是不可見的,當存在編譯報錯時,難以排查。使用常量表達式替換宏是一個比較好的做法,如下:

    #define ASPECT_RATION 1.653
    --> const double AspectRation = 1.653;
    
  2. #define沒有作用域的概念,一旦宏被定義,他就在其後的編譯過程中有效(除非觸發#undef)。

  3. 使用#define定義的宏來當做函數,由於括號問題容易引入異常。可使用template inline函數替代。如下:

    #define CALL_WITH_MA(a, b) f((a) > (b) ? (a) : (b))   // CALL_WITH_MAX(++a, b),a被累加二次,當 a+1 > b時。
    --> 
    template<typename T>
    inline void callWithMax(const T& a, const T&b)
    {
        f(a > b ? a :b);
    }
    

條款03:儘可能使用const

const允許指定一個語義約束,從而獲得編譯器的幫助,確保約束不會被違反。
1、const修飾指針

char greeting[] = "hello";
const char *p = greeting;  // const出現在\*號左邊,表示被指物是常量
char* const p = greeting;  // 出現在\*號右邊,表示指針自身是常量。

2、const修飾迭代器

std::ventor<int> vec;
const std::vector<int>::iterator iter = vec.begin();      // iter是個常量,不能指向其它迭代器
std::ventor<int>::const_iterator cIter = vec.begin();     // cIter指向的對象時常量,不能被更改

3、const成員函數
const成員函數是指只能讀取成員變量,而不能改變成員變量(static除外)。兩個成員函數如果只是常量性(constness)不同,可以被重載。

  • bitwise constness(physical constness):不更改對象內任何一個bit

    class CTextBlock {
        public:
            ...
            char & operator[] (std::size_t position) const {  // bitwise聲明,但其實不適當,原因是返回值可以被修改。
                return pText[position];
            }
        private:
            char *pText;
    };
    
  • logical constness:const成員函數可以修改對象內某些成員變量,但客戶端偵測不出來。

     使用 mutable  關鍵字修飾的成員變量,表示總能可以被更改,即使在const成員函數內。
    
  • 在const和non-const成員函數中避免重複
    考慮到兩個成員函數的功能幾乎一樣,唯一不同在於一個返回const,另一個返回non const,所以實現兩個這樣的函數,容易造成代碼重複。
    一種可用的方法是,將重複代碼放到一個新的函數調用,但這種方式還是存在問題:函數調用、兩次return等。另一種方式是另其中一個調用另一個

    class TextBlock {
    public:
    	const char& operator[] (std::size_t position) const
    	{
    	    ...
    	    ...
    	    ...
    	    return text[position];
    	}
    	char& operator[] (std::size_t position)
    	{
    	    return const_cast<char&>(
    	        static_cast<const TextBlock&>(*this)[position]);
    	}
    	...
    };
    

條款04:確定對象被使用前已被初始化

C++規定,對象的成員變量初始化動作發生在進入構造函數本體之前,所以對於構造函數,最好實現成員初始化列表。值得注意的是,class的成員變量總是以其聲明次序被初始化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章