默認情況下,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往往比較適當。