標籤:

為什麼 C++ 有指針了還要引用?


Stroustrup: C++ Style and Technique FAQ

Why does C++ have both pointers and references?

C++ inherited pointers from C, so I couldn"t remove them without causing serious compatibility problems. References are useful for several things, but the direct reason I introduced them in C++ was to support operator overloading.


因為加入引用是為了支持operator overloading。這裡有一個假設,如果沒有引用,那麼,用指針來operator overloading操作。

A operator +(const A *a, const A *_a);

那麼使用的時候,a + b,這樣看起來是不是很難受。

而引入引用的概念,既可以滿足overload operator,也不失重載value和pointer的靈活性。而且引用還帶來一個指針無法替代的特性: 引用臨時對象。因為引用必須在定義的時候就賦值,以後無法更改。


C++ FQA Lite: References

When should I use references, and when should I use pointers?

FAQ: Use references unless you can"t, especially in interfaces. In particular, references can"t point to NULL, so you can"t have a "sentinel reference". C programmers may dislike the fact that you can"t tell whether a modified value is local or a reference to something else. But this is a form of information hiding, which is good because you should program in the language of a problem rather than the machine.

FQA: As with most duplicate features, there"s no good answer to this question.

C++ programmers use references to denote "a pointer which can"t be null and points to a single object rather than an array". Using pointers in these cases confuses people because they assume that pointers are used in the other cases. You don"t want to confuse people, so you use references to pass arguments to functions. Then it turns out that sometimes you want to pass a null pointer to those functions, and you change references to pointers throughout the code. C++ code ends up containing loads of pointers and references without an apparent reason for the choice made in each particular case.

If you choose to use a reference, make sure you don"t need null pointers, pointer arithmetics or reseating. You can"t have arrays of references, and you can"t store references in container classes, because that would require having uninitialized references and/or pointers to references, and you can"t have that. Member references in classes/structs must be initialized in constructors using the ridiculous colon syntax. This makes it harder to reuse initialization code in different constructors, and the problem propagates to the classes using your class as a member since you can"t provide a default constructor. There are "smart pointers" (objects with overloaded -&> and *operators), but there are no "smart references" (you can"t overload the dot), so you won"t be able to easily switch to something "smart" later - but that"s probably rarely bad since smart pointers are rarely good.

If you choose to use a pointer, make sure you don"t confuse other C++ programmers. Pointers to objects of classes with overloaded operators lead to code like (*parr)[i], which gets annoying. In many cases the compiler won"t warn you when a pointer is left uninitialized, which may lead to errors harder to debug than simple null pointer dereferencing (not to mention security holes - but there"s enough other possibilities for these in a C++ program to make this a separate issue).

These problems mean that in many situations, you must choose between two almost equally bad alternatives. While many people successfully use C pointers in C, it doesn"t mean that always choosing pointers over references in C++ produces no new problems - C++ has features, and C++ programmers have habits interacting badly with pointers.

But this, in turn, doesn"t invalidate the argument "pointers are better than references because it"s easy to see whether a side-effect is local or not". Of course the behavior of references is "information hiding" - but is it the kind of information you would like to be hidden? Isn"t information hiding about making it easy to figure out what a program does? How does hiding side effects, which are a very basic cross-cutting semantical aspect of any imperative language, make the code closer to "the language of the problem"?


這個在《C++語言的設計與演化》上面有詳細說明,原因就是為了支持操作符重載。對於很多C++語法為什麼這麼設計都可以在這本書上找到答案。


是這樣的。一般來說指針和引用基本可以互換使用,這也是為什麼 java 只有引用就夠了。c++ 指針的概念完全是因為 c 語言的歷史遺留,為了兼容 c 而設計的。好的,那你會問,那為什麼不直接用指針,還要搞個引用這種玩意?這是因為 c++ 里有個叫運算符重載的東西,所以 *pointer 這個表達式很有可能並不是直接取值的意思,因為*被重載了。你問我怎麼會有這種鬼玩意?去看看 C++ RAII 的設計,對一個智能指針對象比如 scoped_ptr 取值得到的不是這個智能指針本身,而是他所指向的對象的值,這聽起來有些繞口。所以當遇到這個情況,我們需要一個備胎來代替*的作用,所以就有了引用這玩意,C++ 的創始人可是真任性呢。

C++ 是一種非常複雜的語言,很有可能是這個世界上最複雜的語言。它的複雜來自於他的靈活,一把鋒利的雙刃劍。


不擔心 NULL 的問題,寫代碼方便(不需要 * 來 dereference )。


一方,為了對象,而「引用」。

另一,為了指針,而「替用」。


C++為啥要有引用?

因為運算符重載。

C++為啥要有異常?

因為沒辦法返回一個「空引用」。


指針並非總是很方便的,比如運算符重載,用指針寫到最後會變成一大串又臭又長的東西


用引用最大的好處就是不用再像指針那樣判空了,但實際上他們編譯生成的彙編代碼是一模一樣的


在某些運算符重載,以及複製構造函數的場景下,可能會不得不使用"引用"。


因為引用是編譯器層的東西, 編譯完後並不會佔用真正的內存. 而指針是個數據, 是要單獨佔用內存保存的.

更新一下:

說"引用編譯玩後不會佔內存",這種說法不太嚴謹. 應該說引用是個概念, 概念本身不佔內存. 而實現引用的通常方式為保存其引用對象的指針,而此指針會佔內存,但不是引用占的內存了.

就像類本身不佔內存, 但對象會佔內存一樣


推薦閱讀:

C語言如何執行buf中的代碼?
怎樣才是一個基本水平的c++程序員?
C++11中用{}初始化,有等於號和沒等於號的區別是什麼?
聲明多個指針時,為什麼實際只有第一個是指針?

TAG:C |