4 設計與宣告

2021-09-12 14:33:58 字數 2501 閱讀 3715

理想上,如果客戶企圖使用某個介面卻沒有獲得預期行為,**就不應該通過編譯。

class

date

// 第一步改動:指定引數次序

struct day

int val;};

struct month

;struct year

;class date

;// 第二步改動:限定引數範圍(使用enum或者以函式替換物件)

class

month..

.static month dec()

private

:explicit

month

(int m);.

..};

date d

(month::

mar(),

day(30)

,year

(1995))

;

新type的物件應該如何被建立和銷毀?

物件的初始化和物件的賦值該有什麼樣的差別?

新type的物件如果被passed by value,意味著什麼?

什麼是新type的「合法值」?

你的新type需要配合某個繼承圖系嗎?

你的新type需要什麼樣的轉換?

什麼樣的操作符和函式對此新type而言是合理的?

什麼樣的標準函式應該駁回?

誰該取用新type的成員?

什麼是新type的「未宣告介面」?

你的新type有多麼一般化?

你真的需要乙個新type嗎?

1、pass-by-reference-to-const不會觸發任何建構函式和析構函式,因為不會建立新物件。

2、避免物件切割行為,將derived物件賦值到base物件時,僅會複製base物件部分成員。

3、上述規則不適用內建型別、stl迭代器和函式物件,對它們而言,pass-by-value比較適當。

語法一致性。所有成員變數都通過成員函式訪問。

使用函式訪問可以對成員變數的處理有更精確的控制。(唯讀、只寫等)

封裝。為」所有可能的實現「提供彈性,public意味著不封裝,即不可改變,取消乙個public成員變數影響極大。

protected並不比public更具封裝性。

乙個同樣的功能,成員函式能做,非成員非友元函式都能做,使用後者更佳。因為這樣的做法不會增加」能夠訪問class內之private成分」的函式數量。

寧可拿non-member non-friend函式替換member函式,這樣做可以增加封裝性、包裹彈性和機能擴充性。

// 將允許引數進行隱式型別轉換的函式寫成成員函式

class

rational

;rational x(1

,8);

rational y(1

,2);

rational rel = x * y;

// right

rel = x *2;

// right, 2就是int-to-rational

rel =

2* x;

// error,不支援

只有當引數被列於引數列內,這個引數才是隱式型別轉換的合格參與者。所以rel = x * 2可以,但是rel = 2 * x不行,原因是前者中2位於x.operator*()的引數列內。可作下述改進:

// 將operator*宣告為non-member函式,就可以提供這樣的引數列表

const rational operator*(

const rational &lhs,

const rational rhs)

綜上,如果你需要為某個函式的所有引數(包括被this指標所指的那個隱喻引數)進行型別轉換,那麼這個函式必須是個non-member。

標準庫的swap演算法實現:

namespace std 

}

針對piml(pointer to implementation)手法的物件,swap效率很低:

class

widgetimpl

;class

widget

private

: widgetimpl* pimpl;

正常情況下,置換widget物件的值,只需要置換內部的pimpl指標即可,但是使用預設的swap演算法,會將物件內部的成員複製三次,效率非常低。

處理方式:

1、提供乙個public swap成員函式,讓它高效地置換物件值。

2、在class或template的命名空間內提供乙個non-member swap,並令它呼叫上述swap成員函式。

3、如果正在編寫乙個class(而非class template),為它特化std::swap,並令它呼叫swap成員函式。

Effective C 筆記 4 設計與宣告

條款18 讓介面容易被正確使用,不易被誤用 請記住 好的介面很容易被正確使用,不容易被誤用。你應該在你的所有介面中努力達到這些性質。促進正確使用 的方法包括介面的一致性,以及與內建型別的行為相容。阻止誤用 的辦法包括建立新型別 限制型別上的操作,束縛物件值,以及消除客戶的資源管理責任。trl sha...

設計與宣告

預設情況下c 是以值傳遞的形式傳遞物件到函式的。除非特別指定,否則函式引數都是以實際實參的副本為初值。呼叫端所獲的也是函式返回值的乙個副本。這些副本是由物件的拷貝建構函式產生,這會使值傳遞非常費時。特別是在乙個結構複雜的類中,例如 class student public person當有以下函式 ...

設計與宣告

條款18 讓介面容易被正確使用,不易被誤用 條款19 設計class猶如設計type 條款20 寧以pass by value to const替換pass by value 預設情況下c 以by value方法給物件傳遞引數,函式引數都是物件的副本,這些副本是由物件的copy建構函式產出,這可能使...