讀書筆記《Effective c++》 條款20 寧以pass-by-reference-toconst替換pass-by-value


默認情況下,c++以by value方式傳遞對象(函數參數、返回值),這些副本是由對象的copy構造函數產出。


傳值有兩個問題:


a.效率低下。


b.可能產生對象切割(slicing)問題

class Base
{
public:
	virtual void test() const
	{
		cout << "base.test()" << endl;
	}
};

class Derive : public Base
{
public:
	virtual void test() const override
	{
		cout << "Derive.test()" << endl;
	}
};

void show1(Base b)
{
	b.test();
};

void show2(const Base& b)
{
	b.test();
};

int main()
{
	show1(Derive{});  // 輸出 base.test()
	show2(Derive{});  // 輸出 Derive.test()

	return 0;
}
上面這段代碼,show1函數中,即使你傳給他一個子類,他調用的還是父類的test虛函數,也就是子類的信息被切割了。


出現這個問題的原因是,show1的參數是由Base類的複製構造函數(以Derive{}爲參數)創建,說到底他只是Base的一個對象。這通常不是我們在實際項目中希望發生的事情。


這與delphi不同,delphi的對象本身就是指針,不存在by value傳遞的問題,也就是不會有對象被切割的問題。


補充:

  我記得好像google的c++編程規範裏要求,如果是以引用&傳參,那麼必須加上const,如果希望在函數中修改參數的值,那麼請把參數修改爲指針*而不是使用引用&(待驗證)


總結:

  a.儘量以pass-by-reference-to-const替換pass-by-value。前者通常比較高效,並可避免切割問題。

  b.以上規則並不適用於內置類型,以及stl的迭代器和函數對象,對他們而言,pass-by-value往往比較適當。


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