讀書筆記《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版本可避免代碼重複。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章