1. 程式人生 > 其它 >Effectice C++ 1 讓自己習慣C++

Effectice C++ 1 讓自己習慣C++

讓自己習慣C++

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

單純的常量,最好用constenums替換#defines
形似函式的巨集,用函式inline來替換#defines

條款03: 儘可能使用const

const出現在*左邊,說明被指物是一個常量,出現在右邊說明指標本身是一個常量,出現在兩邊說明都是常量。

std::vector<int> vec;
const std::vector<int>::iterator iter = vec.begin();  //等價於T* const
*iter = 10; //right
++iter; //error,不能改變指向的物件

std::vector<int>::const_iterator cIter = vec.begin(); //等價於const T*
*iter = 10; //error
++iter; //right
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]);
  }
private:
  std::string text;
};

這段程式碼使用const operator[]

實現了non-const的功能,主要進行了兩次強制型別轉換。首先將*this轉換為const TextBlock&,以此可以呼叫const operator[],然後使用const_cast<char&>去掉const屬性,轉換為char&

使用non-const成員函式呼叫const成員函式可以,但是反過來絕對不行,並且non-const呼叫const可以避免程式碼重複。

條款04:確定物件被使用前已先被初始化

初始化的順序:基類->派生類.按照初始化列表裡的順序初始化,儘量按照定義的順序來寫初始化列表的順序。

函式內的static物件成為local static

物件,其他的稱為non-local static物件。
為了免除“跨編譯單元初始化次序”問題,用local static物件替代non-local static物件。

//FileSystem.h
class FileSystem {
public:
  std::size_t numDisks() const;
};
extern FileSystem tfs; //non local static
class Directory {
public:
  Directory(params);
};

Directory::Directory(params) {
  std::size_t disks = tfs.numDisks(); //使用tfs物件
}
Directory tempDir(params);

上述程式碼就會出現初始化次序的問題,當我們呼叫初始化tempDir的時候無法保證tfs被初始化,因為tfs屬於其他檔案的內容,不一定初始化了。

C++保證:函式內的local static物件會在“該函式被呼叫期間” “首次遇上該物件定義式”時被初始化。以“函式呼叫”替換“直接訪問non-local static”物件,保證引用的物件已經初始化。

class FileSystem{...};

FileSystem& tfs() {
  static FileSystem fs; //定義並初始化一個local static物件
  return fs;
}

class Directory{...};
Directory::Directory(params) {
  std::size_t disks = tfs().numDisks(); //使用tfs物件,此時執行tfs的初始化
}
Directory& tempDir() {
  static Directory td;
  return td;
}