尽量用pass-by-reference-to-const(const引用)替换pass-by-value(传值)
? ? ? ? 默認(rèn)情況下C++以pass-by-value傳遞對象至函數(shù)(或從函數(shù)返回)。
? ? eg1:
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; };? ? ? ? 考慮下面調(diào)用函數(shù): bool validateStudent(Student s); // 函數(shù)以 by value 方式接受參數(shù) Student plato; bool platoIsOk = validateStudent(plato); // 調(diào)用函數(shù)? ? ? ? Student的copy構(gòu)造函數(shù)會被調(diào)用,以plato為藍(lán)本將s初始化。而當(dāng)validtaeStudent返回時s會被銷毀。詳細(xì)深究的話,應(yīng)該是以by value方式傳遞一個Student對象會導(dǎo)致調(diào)用一次Student copy構(gòu)造函數(shù),一次Person copy構(gòu)造函數(shù),4次String copy構(gòu)造函數(shù);相應(yīng)銷毀時總共需要調(diào)用6次析構(gòu)函數(shù)。所以總成本是“六次構(gòu)造函數(shù)和六次析構(gòu)函數(shù)”!? ? ? ? 使用pass by reference to const進(jìn)行回避:
bool validateStudent(const Student& s);? ? ? ? 這種傳遞方式效率就高很多,沒有任何構(gòu)造函數(shù)或析構(gòu)函數(shù)被調(diào)用,因為沒有對象被創(chuàng)建。這里的const使用是重要的,不這樣做的話調(diào)用者會憂慮validateStudent會不會改變他們傳入的哪個Student。
? ? ? ? 以by reference方式傳遞參數(shù)還可以避免slicing(對象切割)問題。
? ? ? ? 如果函數(shù)參數(shù)是基類對象,當(dāng)傳入一個派生類對象時,會造成派生類對象相比基類對象“之所以是個派生類對象”的所有特性化信息都會被切除。解決切割(slicing)問題的辦法,就是以by reference to const的方式傳遞參數(shù)。
? ? ? ? 閑談:有一次面試的時候問到了我這個問題,沒有很好的回答上來“多態(tài)發(fā)生為什么需要傳指針而不直接傳遞對象,傳遞對象有什么后果?”,現(xiàn)在可以很好的總結(jié)出答案。
? ? ? ? 由C++編譯器的角度來看,references往往以指針實現(xiàn)出來,一次pass by reference 通常意味真正傳遞的是指針。如果對象屬于內(nèi)置類型(例如int),pass by value往往比pass by reference的效率高些(原因請看:C++ 傳參時傳內(nèi)置類型時用傳值(pass by value)方式效率較高)。
? ? 1、內(nèi)置類型都相當(dāng)小,因此有人覺得,小型types都是pass-by-value的合格候選人,這個理論不可靠,對象小并不意味著其copy構(gòu)造函數(shù)并不昂貴。許多對象(包括大多數(shù)STL容器)內(nèi)容的東西只比一個指針多一些,但復(fù)制這種對象卻需承擔(dān)“復(fù)制那些指針?biāo)傅拿恳粯訓(xùn)|西”,那將非常昂貴。
? ? 2、即使小型對象擁有并不昂貴的copy構(gòu)造函數(shù),但效率優(yōu)化上可能有爭議。某些編譯器會針對“內(nèi)置類型”進(jìn)行優(yōu)化,比如某些編譯器拒絕把只由一個double組成的對象放進(jìn)緩存器,但是很樂意在一個正規(guī)基礎(chǔ)上對光禿禿的doubles那么做。這種情況下,更應(yīng)該以by reference方式傳遞此等對象。
? ? 3、作為一個用戶自定義類型,其大小容易有所變化。一個type目前雖然小,將來也許會變大,因為其內(nèi)部實現(xiàn)可能改變。
結(jié)論:
? ? ? ? 1、盡量以pass-by-reference-to-const替換pass-by-value,前者通常畢竟高校,并可避免切割問題(slicing problem)。
? ? ? ? 2、以上規(guī)則并不適用于內(nèi)置規(guī)則,以及STL的迭代器和函數(shù)對象。對它們而言,pass-by-value往往比較適當(dāng)。
總結(jié)
以上是生活随笔為你收集整理的尽量用pass-by-reference-to-const(const引用)替换pass-by-value(传值)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html鼠标移除的效果,css实现鼠标移
- 下一篇: CIA-SSD: Confident I