Effictive C++條款整理計劃(1-10)
阿新 • • 發佈:2018-12-23
-
第一條:視C++為一個語言聯邦
該條款的理解是,把c++看成一個由相關語言組成的聯邦,而非單一的語言,在運用某個次語言的時候,應該遵守各個次語言的約定和規則,保證其簡單,直觀易懂。
c++次語言有以下四種:
C語言 c++是C語言的超集
Object-Oriented C++ 古典c++,即面向物件設計之古典規則在c++上最直接的實施。
Template c++ 泛型程式設計(很少被專案大量使用,難度)
STL STL是Template C++中特殊的一個。 -
第二條:儘量以const、enum、inline替換 #define
對於單純常量,最好以const物件或enum替換define
對於形似函式的巨集,最好用inline函式來替換巨集 -
第三條:儘可能使用const
對於const的使用,可以參考const的使用
const的時候,可以保證程式的健壯性。需要注意的是在c++11中新增了一個關鍵字constexpr,這個關鍵字和const的區別是,const表示的是程式在執行期的不可修改屬性,而constexpr可以表示在編譯期間的不可修改屬性。 -
第四條:確定物件被使用前已被初始化
該條款的意思一個物件的生成必須遵循RAII,即構造即初始化,所有的物件在生成時,其中的成員必須在構造中進行初始化。推薦使用初始化列表進行初始化,這比在建構函式中進行初始化,少了資料的拷貝。 -
第五條:瞭解c++默默編寫並呼叫了哪些函式
該條款的意思是一個空類中,編譯器會為該類生成以下幾個函式:預設建構函式,預設拷貝函式,預設解構函式,預設operator=函式,在c++11之後,還有一個預設移動建構函式
- 第六條:若不想使用編譯器自動生成的函式,就該明確拒絕
該條款的意思是,如果不想使用條款5預設的函式,就應該進行明確的拒絕。在c++11以前,可以將上述函式只宣告而不是實現。在c++之後,可以使用delete進行明確的拒絕。 - 第七條:為多型基類宣告virtual解構函式
該條款防止,當一個new出來的子類地址賦值給基類指標是,假如基類的解構函式不是virtual函式,則會導致子類的解構函式不會被呼叫,從而導致記憶體洩露。 - 第八條:別讓異常逃離解構函式
不能在解構函式中丟擲異常。個人建議儘量不要使用丟擲c++異常,而是在出問題的地方,將異常情況解決或者記錄,而不是丟擲。 - 第九條:決不再構造和解構函式過程中呼叫virtual函式
在建構函式或者解構函式中呼叫virtual函式,有可能導致不可預期的行為發生,所以絕不應該在解構函式和建構函式中呼叫virtual函式。 - 第十條:令operator=返回一個reference to *this
該協議適用於所用的+=,-=等操作符
#include <iostream>
using namespace std;
//const 替換 #define
//#define PI 3.1415926
const double Pi = 3.1415926;
//enum 替換 #define
//#define NumTurns 5
class GamePlayer
{
public:
GamePlayer() { m_scores[NumTurns] = { 0 }; }
private:
enum {
NumTurns = 5
};
int m_scores[NumTurns];
};
//以inline 替換 #define
template<typename T>
inline const T& callWithMax(const T& a, const T& b)
{
return a > b ? a : b;
}
class Student
{
public:
Student(int age):m_age(age) {}
~Student() {}
private:
Student(const Student&) = delete; // c++11之後,推薦
//Student& operator=(const Student& rhs);//c++11之前,只宣告,不實現
//條款10
Student& operator=(const Student& rhs)
{
if (this == &rhs)
{
return *this;
}
m_age = rhs.m_age;
return *this;
}
int m_age;
};