effective c++ 20 傳引用代替?zhèn)髦?/h2>
本節(jié),作者開始討論引用。我們知道c語言已經(jīng)有了指針,通過指針我們也就可以修改變量本身,而不是修改變量的副本(傳值), 那么在c++中又搞出來個引用, 那么其是不是有點重復(fù)?
分析
我們知道在函數(shù)的傳參中,如果傳遞的是指針, 那么就不可避免的要進(jìn)行取地址和解引用,如下面的這段代碼所示,就需要使用"&“和”*"。這就可給我們的代碼增加了一定的復(fù)雜性。其實c++引入引用也就是為了簡化這種寫法。
#include <iostream>
void print(int* a)
{
*a = 4;
std::cout << *a << std::endl;
}
int main()
{
int a = 3;
print(&a);
}
上面的代碼修改成用引用的方式,是不是就簡化了很多。
#include <iostream>
void print(int& a)
{
a = 4;
std::cout << a << std::endl;
}
int main()
{
int a = 3;
print(a);
}
因此我們在c++中,涉及傳參的時候,要盡量使用引用。但是要強(qiáng)調(diào)的是,引用并不能取代指針,涉及內(nèi)存的操作的時候,指針還是不可替代的。
由于引用有指針的特性,在傳參的時候是沒有copy的行為的。例如下面這個validateStudent函數(shù),使用了常引用作為入?yún)?,避免了對象的拷貝。如果用傳值的方式?其內(nèi)部有多個string對象要涉及拷貝,這將是低效的。
class Person
{
public:
Person() : name("AAAA"), addr("BBBB")
{
}
virtual ~Person() {}
private:
std::string name;
std::string addr;
};
class Student : public Person
{
public:
Student() : schoolName("CCCC"), schoolAddr("DDDD")
{
}
~Student() {}
private:
std::string schoolName;
std::string schoolAddr;
};
bool validateStudent(const Student& s);
另外, 由于引用的背后是由指針實現(xiàn)的,所以其將擁有"多態(tài)"的功能。 如下面中的printNameAndDisplay函數(shù), 其入?yún)⑹且粋€Window類的引用,在類的繼承關(guān)系上,WindowWithScrollBars繼承于Window。因此當(dāng)傳入的對象是Window對象時,w.display將調(diào)用window類的display方法,當(dāng)傳入的參數(shù)是WindowWithScrollBars類的對象時,w.display將調(diào)用WindowWithScrollBars類的display方法。
class Window
{
public:
std::string name() const { return "WINDOW"; }
virtual void display() const
{
std::cout << "Display: window" << std::endl;
}
};
class WindowWithScrollBars : public Window
{
public:
void display() const
{
std::cout << "Display: window with scroll bars" << std::endl;
}
};
void printNameAndDisplay(const Window& w)
{
std::cout << w.name();
w.display();
}
上面主要講解了傳引用的好處, 那么什么時候我們引用考慮傳值呢?
作者這里也給出了解答, 下面三種場景可以考慮直接傳值:
- 內(nèi)置類型(只讀不修改時)
- STL迭代器
- 函數(shù)對象
關(guān)于STL迭代器和函數(shù)對象為什么可以考慮傳值,我在知乎上搜到了下面的解釋,我覺得比較有道理:
很多時候迭代器可以做成可平凡復(fù)制的小對象(有時就是裸指針或裸指針直接外包),這時值傳遞迭代器和傳遞一個指針開銷相同。不過例外也是存在的。文章來源:http://www.zghlxwxcb.cn/news/detail-454766.html
函數(shù)對象的話,無狀態(tài)函數(shù)對象和函數(shù)指針是常見的情況。不過“大塊頭”的函數(shù)對象(如 std::function 或狀態(tài)龐大的函數(shù)對象)也不能說少見。這時選擇傳值還是 const 引用可能就需要斟酌。文章來源地址http://www.zghlxwxcb.cn/news/detail-454766.html
總結(jié)
- 盡量以傳常引用去替代傳值。前者通常比較高效,并且可以避免切割問題。
- 以上規(guī)則并不適用于內(nèi)置類型 ,以及STL的迭代器和函數(shù)對象,對它們而言,傳值往往比較合適。
到了這里,關(guān)于effective c++ 20 傳引用代替?zhèn)髦档奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!