iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
自我挑戰組

Effective C++ 讀書筆記系列 第 27

[Day 27] Prefer pass-by-reference-to-const to pass-by-value (1)

  • 分享至 

  • xImage
  •  

前言

今天的守則是討論function中的parameter傳遞的方式,傳參數的時候可能沒想太多就直接把要用的東西傳入,今天就來看看其中可能更好的做法~

Pass by value所費不貲

今天的守則是:

Prefer pass-by-reference-to-const to pass-by-value

這是什麼意思呢?
我們都知道一般function的傳參數方式,而最常見的就是pass by value。而function在接收到參數的時候,他會用收到的參數的copy來做引數的初始化,而call function的人則會接收到return value的copy;這些copy行為都是用那些物件的copy constructor來完成的。這有什麼後果呢?代表pass by value這件事背後其實花費很多操作。以下面的例子為例,首先我們有兩個class:

class Person
{
public:
    Person();
    virtual ~Person();
private:
    std::string name;
    std::string address;
};

class Student: public Person
{
public:
    Student();
    ~Student();
private:
    std::string schoolName;
    std::string schoolAddress;
};

然後,有一個function,需要Student物件的input,並去call它來用:

bool validateStudent(Student s);

Student plato;
bool platoIsOK = validateStudent(plato);

以上validateStudent()就是一個pass by value的function,下面將plato傳入的時候經歷了哪些操作呢?
如同前面講的,要用傳入的物件來製作copy,所以 1.Studentcopy constructor會被call起來初始化Student物件s,而2.在function結束return value時也會把這個s給destroy掉─也就是callStudentdestructor。而1跟2其中又牽涉到裡面各member的copy constructor跟destructor,例如Student裡面的兩個string objects,另外又因Student是繼承自Person,所以背後還有Person的copy constructor跟destructor!Person裡面又有自己的兩個string member...。全部開展來看,這個pass by value的call法可是要價6個constructor跟destructor啊!

Pass by reference (to const)好處多!

那有什麼方法可以省下這些操作呢?那就是 pass by reference to const 啦!
延續同樣的例子,會長這樣:

bool validateStudent(const Student& s);

這就可以省去那些constructor與destructor了!這種call法就不會在function內產生新的物件。

值得注意的是我們還加了 const,這個很重要!原本pass by value的做法,因為會在function內產生新的object,所以原本傳入的object肯定不會被改到,因為所有的改動都在它的copy上發生;因此如果要改用pass by reference,我們應該也要確保原本傳入的object不會被改動!因此要加const

而pass by reference還有另一個好處,就是避免slicing problem
如果一個derived class的物件被function pass by value並用base class物件接住它,那function裡面copy出來的會是base class的物件!因為它是設法會去initialize base class物件,而用的是derived class的物件,那其中derived class比base class多出來的部分就會被 "sliced off" 了。通常我們傳入derived class的物件應該不預期它變成是base class的操作。

明天我們再來深入看看"sliced-off"問題,以及又有什麼情況下,"pass by value"可能是比較好的選擇。


上一篇
[Day 26] Treat class design as type design
下一篇
[Day 28] Prefer pass-by-reference-to-const to pass-by-value (2)
系列文
Effective C++ 讀書筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言