1. 程式人生 > >讀書筆記《Effective c++》 條款03 儘可能使用const

讀書筆記《Effective c++》 條款03 儘可能使用const

const是一種約束,告訴編譯器和其他程式設計師,這個值不要被修改。

a.函式返回值是常量: 例如有理數的乘法過載:

const Rational operator* (const Rational& lhs, const Rational& rhs);
這樣寫可以避免一些暴行,例如
Rational a, b, c;
(a * b) = c;

b.const成員函式

將const實施於成員函式的目的,是為了確認改成員函式可作用於const物件身上。

兩個成員函式如果只是常量性不同,可以被過載。例如:

using std::cout;
using std::endl;
using std::string;

class TextBlock
{
public:
	const char& operator[](std::size_t position) const
	{
		cout << "const版本" << endl;
		return text[position];
	}
	char& operator[](std::size_t position)
	{
		cout << "普通版本" << endl;
		return text[position];
	}
	TextBlock(const string& s) :text{ s }
	{

	}
private:
	std::string text;
};

void print(const TextBlock& tb)
{
	cout << tb[0] << endl;
}

int main()
{
	TextBlock tb{ "Hello" };
	cout << tb[0] << endl;       // 普通版本

	const TextBlock ctb{"World"};
	cout << ctb[0] << endl;      // const普通版本

	print(TextBlock{ "OhGod" }); // const普通版本
}

此小節也引出了mutable關鍵字。

c.在const和non-const成員函式中避免重複

上面的類中,constt版本和non-const版本在實際的程式碼中可能會有大量相同的程式碼,所以如果像過載一樣,能讓non-const版本呼叫const版本,

將會減少很多重複程式碼:

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

		//cout << "普通版本" << endl;
		//return text[position];
	}
先將*this轉換成const物件,然後就可以呼叫const版本的[],最後將返回值去const。

但是如果反過來,用const版本呼叫non-const是肯定不行的,因為const承諾不改變物件的邏輯狀態。

總結

a.將某些東西宣告為const可以幫助編譯器偵測出錯誤語法。const可被施加於任何作用於內的物件、函式引數、函式返回型別、成員函式本體。

b.編譯器強制實施bitwise constness,但你編寫程式時應該使用“概念上的常量性”(conceptual constness)。

c.當const和non-const成員函式有著實質等價的實現時,令non-const版本呼叫const版本可避免程式碼重複。