[TOC] 0. 序言 工作的需要,最近在接手一個C++項目。自己在校學習期間,因為懶惰,對於C++這樣的巨型語言,是能躲就躲的,因此學的一知半解,導致現在工作時的無能為力。但是,指責所在,躲無可躲,只能做一些亡羊補牢之事。下麵的一系列文章,就是自己邊工作邊學習的記錄,算是學步時的點滴。內容會持續更 ...
目錄
0. 序言
工作的需要,最近在接手一個C++項目。自己在校學習期間,因為懶惰,對於C++這樣的巨型語言,是能躲就躲的,因此學的一知半解,導致現在工作時的無能為力。但是,指責所在,躲無可躲,只能做一些亡羊補牢之事。下麵的一系列文章,就是自己邊工作邊學習的記錄,算是學步時的點滴。內容會持續更新,有錯誤之處,敬請指教。
1. class編寫過程中的註意事項
在編寫類的時候,一般將類的申明和實現分開,這樣便於類的實現和調用。比如定義一個名為:
頭文件中最好用防衛式申明,目的是防止文件的內容被多次包含(多次包含之後會出現重覆定義或者多次申明的錯誤。)如:
laptop.h
#ifndef _PROJECT_SUBFOLDER_LAPTOP_H_ // 此處推薦使用Google編程規範:項目名_子文件路徑_文件名
#define _PROJECT_SUBFOLDER_LAPTOP_H_
// define a laptop class
calss Laptop // 類名首字母大寫
{
public:
// member functions; // 成員函數一般為public屬性;
double getVolt() const { return volt_;} //不會改變成員變數的函數申明為常函數const;
private:
// member attributes;// 成員變數一般設為private;
};
#endif // _PROJECT_SUBFOLDER_LAPTOP_H_
類的構造函數
為了通用性,一般為一個類設至少兩個構造函數,0參數構造函數,多參數構造函數;當使用多參數構造函數的時候,推薦使用**初始化列表**來初始化成員變數。(在函數內的叫賦值,不是初始化。賦值和初始化列表的區別是記憶體開銷上不一樣。)
class Laptop
{
public:
Laptop(){}//預設構造函數
Laptop(double value = 0, double volt)// 多參數構造函數,註意不能將所有的值設為預設值。請思考為什麼
:value_(value), volt_(volt){} // 初始化列表
private:
// ...
}
儘可能使用引用傳參
引用傳參比值傳遞的優點是效率高,開銷低。另外,傳引用可以數據雙向傳遞(這在很多情況下是不希望發生的,這時可以傳遞**常引用**)。另外,對於內置類型,傳值和傳引用的效率相差不多,一般可以傳值,對於構造類型,請傳引用。關於**傳值**,**傳引用**,**傳指針**之間的區別和聯繫,將在專門的文章里討論。
在可能的情況下,函數返回值也請儘量使用引用。這裡需要註意的是,將引用作為函數返回值的條件是引用的宿主對象至少要在函數調用現場有生命並可見!!,否在,不能將應用返回,因為局部變數在函數調用結束的時候就已經被回收,它的生命周期已經到了盡頭,再去返回它的引用,明顯是會出錯的。將應用作為函數返回值的一個很典型的應用是對一些二元操作符的重構。這裡給出幾個例子:
例1:+=
重構
class Point
{
public:
Point(){}
Point(double x, double y)
:x_(x), y_(y){}
void setx(double x){x_ = x;}
void sety(double y){y_ = y;}
Point & operator += (Point & b)
{
this -> x_ += b.x_;
this -> y_ += b.y_;
return this;
}
private:
double x_;
double y_;
};
例2:<<
重構
class Point
{
public:
//....
// 顯示點p(x,y)
}
重構/重載要全面
在類中重構或者重載函數的時候,為了使用的方便,請儘可能全面的重構/重載。比如,有一個複數類,裡面重載加法運算符,這時候要考慮到用戶可能會將複數與實數相見,複數與複數相加,實數與複數相加,這些都要進行重載。重構函數的時候也同樣。
外部介面放在類的最前面,寫好使用說明,包括:介面功能的描述,輸入參數的描述,輸出參數的描述。