When should static_cast, dynamic_cast and reinterpret_cast be used?
?這是我偶然在?http://stackoverflow.com/questions/?網頁上發現的一個問題(類似博客園的博問),問題主要是關于詢問應該怎樣使用,以及何時使用C++里面的這幾種類型轉換操作符:static_case, dynamic_cast,以及 reinterpret_cast 。我想這是一個非常典型的問題,因此我就想把這篇帖子轉載到我的博客上,也是我第一篇轉載的文章。
????????????這個問題的原文鏈接是:
????????????http://stackoverflow.com/questions/332030/when-should-staticcast-dynamiccast-and-reinterpretcast-be-used
????????????下面是該貼的內容以及最佳答案,我將答案從英文譯為中文。原文如下:
?
??????????When should static_cast, dynamic_cast and reinterpret_cast be used?
=========
Question:
=========
????????????I am reasonably proficient in C++, but I do not have a lot of experience using the cast operators to convert pointers of one type to another. I am familiar with the risks and benefits of pointer casting, as well as the evils of using C-style casts. What I am looking for is a primer on the proper ways to use the various cast operators in C++.
????????????我熟悉C++,但是我對于使用類型轉換操作符卻沒有什么經驗。如同使用C風格轉換一樣,我熟悉使用其風險但也享受著它的好處。我想知道正確使用這些C++轉換操作符的基本方法。
????????????What are the proper uses of static_cast, dynamic_cast and reinterpret_cast, and how does one decide which one to use in a specific case?
????????????怎樣恰當使用 static_cast, dynamic_cast, reinterpret_cast,怎樣在實際使用中決定到底采用它們中的哪一個呢?
????????????3,107●4●23 asked Dec 1 at 20:11 eJames
?
????????????I'm torn between the top two answers. Thank you all for answering. I have chosen coppro's answer because of the detail he goes into regarding static_cast, and because he gives some indication of which should be used in preference to others. – eJames Dec 1 at 20:55
?
==========
Anwser:
==========
static_cast
static_cast is the first cast you should attempt to use. It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly stating static_cast isn't necessary, but it's important to note that the T(something) syntax is equivalent to (T)something and should be avoided (more on that later). A T(something, something_else) is safe, however, and guaranteed to call the constructor.
static_cast can also cast through inheritance hierarchies. It is unecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn't cast through virtual inheritance. It does not do checking, however, and it is undefined behavior to static_cast down a hierarchy to a type that isn't actually the type of the object.
?
static_cast 是你應該首先嘗試的轉換。它用于隱式類型轉換(例如從 int 到 float,或者從指針到 void*),也可以用于顯示(或隱式)轉換函數。在很多情況下,顯示的書寫 static_cast 并不必要,但是必須注意的是,T(something)的寫法和(T)something的寫法是等效的,并且應該避免后面這種寫法。 T(something, something_else)是安全的,并且會保證調用構造函數。
?
static_cast 也可以用于在類的繼承方向上進行轉換。向上轉換(向父類)是不必要的,當向下轉換時可以用于轉換到 非 virtual的繼承(派生)。static_cast不會做對此轉換做檢查,但是注意如果試圖向并非其子類的對象進行轉換,則屬于未定義行為。
const_cast
const_cast can be used to remove or add const to a variable; no other C++ cast is capable of this (not even reinterpret_cast). It is important to note that using it is only undefined if the orginial variable is const; if you use it to take the const of a reference to something that wasn't declared with const, it is safe. This can be useful when overloading member functions based on const, for instance. It can also be used to add const to an object, such as to call a member function overload.
const_cast also works similarly on volatile, though that's less common.
const_cast 用于去除或者添加變量中的const修飾。其他的C++轉換則做不了這件事(即使 reinterpret_cast?也不行)。注意只有原始變量是常量時,該轉換才是未定義的。如果你把一個const引用轉換到不帶const修飾,則是安全的。這在重載一些基于const定義的成員函數非常有用。也可以用于給一個對象添加const,例如調用一個重載成員函數時。
const_cast 也可以用在轉換 volatile 變量上,盡管很少見。
?
dynamic_cast
dynamic_cast is almost exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You don't have to use it to cast downwards, you can cast sideways or even up another chain. The dynamic_cast will seek out the desired object and return it if possible. If it can't, it will return NULL in the case of a pointer, or throw std::bad_cast in the case of a reference.
?
dynamic_cast 幾乎是多態機制所專用的操作符。你可以把任何 多態類型(至少含有一個虛函數,不管是自身的還是繼承而來的) 的指針或引用轉換到任意的其他對象類型。dynamic_cast 不僅可以向下轉換,還可以橫向甚至轉向其他分支, 它會盡可能選取出你想要的對象并提供。如果它無法轉換,則返回NULL(對指針)或者拋出 std::bad_cast (對引用)。
?
reinterpret_cast
reinterpret_cast is the most dangerous cast, and should be used very sparingly. It turns one type directly into another - such as casting the value from one pointer to another, or storing a pointer in an int, or all sorts of other nasty things. Largely, the only guarantee you get with reinterpret_cast is that if you cast the result back to the original type, you will get the same value. Other than that, you're on your own. reinterpret_cast cannot do all sorts of conversions; in fact it is relatively limited. It should almost never be used (even interfacing with C code using void* can be done with static_cast).
reinterpret_cast 是最危險的一種轉換,應保守使用。它把一種類型直接轉換到另外一個類型,例如把值從一個指針變為另一個,或者把指針存儲成 int,以及所有其他事物。使用reinterpret_cast 我們唯一可以得到的保證是,把轉換結果再轉回原始類型時,它的值將保持不變。此外,則取決與你自己。reinterpret_cast 不能完成所有種類的轉換。實際上它相對而言很受限, 我們應該盡可能不使用它(即使和C代碼做接口,我們通過static_cast 可以使用?void*)。
?
C casts
A C cast ((type)object or type(object)) is defined as the first of the following which succeeds:
const_cast?
static_cast?
static_cast, then const_cast?
reinterpret_cast?
reinterpret_cast, then const_cast?
It can therefore be used as a replacement for other casts in some instances, but can be extremely dangerous because of the ability to devolve into a static_cast, and the latter should be preferred when explicit casting is needed, unless you are sure static_cast will succeed or reinterpret_cast will fail. Even then, consider the longer, more explicit option.
?
C類型轉換 ( (type)object 或 type(object) ) 定義為以下任何一個,假如它能夠成功:
const_cast?
static_cast?
static_cast, then const_cast?
reinterpret_cast?
reinterpret_cast, then const_cast?
所以我們可以在某些場合使用C類型轉換來代替那些顯示的操作符,但是必須強調的是,它有可能成為 static_cast (而static_cast 應該用于必須進行顯示轉換的場合) ,這是極端危險的,除非你確信 static_cast 會成功而 reinterpret_cast 會失敗。即便如此,為長遠考慮,應該明確制定具體的轉換操作符。
?
I hope this helps!
希望這些對你有幫助!
link|flag answered Dec 1 at 20:26 coppro 3,107●4●23
----------------------------------------------------------------------
?
? I hope others up-vote this answer - it's the only one that actually describes static_cast in enough detail, specifically the limitations on casting within an inheritance hierarchy. – Earwicker Dec 1 at 20:32?
?nice answer mate – litb Dec 1 at 20:35?
?Agreed with Earwicker, and +1 from here – jalf Dec 1 at 20:39?
?Can you clean up the const_cast section? It is worded confusingly. The last sentence is repeated. Any cast can add const, only const_cast can remove it. The middle section should read more like: "It is undefined behavior to modify a variable defined as const, only possible through use of const_cast" – Greg Rogers Dec 1 at 21:01
?
你可以整理下 const_cast 哪一段嗎? 描述的比較混亂。最后一句是重復的。任何轉換都可以添加const,但是只有 const_cast 可以去掉const。中間一段似乎更應該理解為:“修改一個聲明為const的變量屬于未定義行為,只有通過 const_cast 才可以辦到”。- Greg Rogers
?
?I would recommend as first option dynamic_cast<> which, of course only works as described above. Whenever you can do dynamic_cast<> it will check that the type is really what you believe. – dribeas Dec 1 at 21:02
===============================================================
static_cast
It is able to do the reverse of what an implicit conversion can do. Meaning: narrow (long -> int), widen (int -> long), base-to-derived, void*-to-T* for example. You can't use it for the stuff that an reversed implicit conversion cannot do. (I.e you cannot cast an int* into int).
用于和隱式轉換可用時的反向轉換。意味著:向窄(long->int),向寬(int->long),父類到子類,void*到T* 等等。不能用于隱式轉換無法完成的反向轉換。(例如把int*轉換為int)。
dynamic_cast
It is used to cast a base pointer into a derived pointer. If the base pointer doesn't point to an object of the type of the derived, it returns 0.?
It is used to cast a base reference into a derived reference. If the reference isn't pointing to an object of the derived, it throws std::bad_cast.?
It can be considered the checked cast equivalent to static_cast, in that it checks whether the object pointed to really is of the derived type.
用于把父類指針轉換為子類指針,如果實際指向不是子類對象,返回0。
用于把父類引用轉換為子類引用,如果實際引用不是子類對象,拋出std::bad_cast。
當檢驗對象是否確實指向子類類型時,可以認為該檢驗等效于static_cast。
reinterpret_cast
It is used to cast a pointer type to a wide enough integral type and back to the original pointer type.?
It is used to cast between pointer types of incompatible types (int* to double* for example). The result of that mapping is unspecified, but it's possible to do so.
用于把指針類型轉換到整形以及轉回到指針類型。
用于在不相容的兩種對象的指針類型之間進行轉換(例如int*到double*)。結果將是無法預料的,但有時可能會這樣做。
const_cast
It is used to cast away const or volatile. It is used in the rare cases when you have a originally non-const object, which is pointed to by a pointer-to-const or referenced to by a reference-to-const. Casting away constness is considered evil and should not be done if it can be avoided.
用于去掉 const 或 volatile 的轉換。它僅僅在很少的情況下使用,即當你擁有const指針指向或const引用引用的一個非const對象時。去掉const的轉換是很“邪惡”的,能不用則不用。
A?C-style cast?is equivalent to the following C++ style casts. The first cast that succeeds is taken (See 5.4 in the Standard):
C轉換和下面首先成功的C++類型轉換等效(參見標準的5.4):
const_cast, static_cast, static_cast followed by const_cast, reinterpret_cast, reinterpret_cast followed by const_cast.
link|flag edited Dec 1 at 20:31 answered Dec 1 at 20:24 litb 31.9k●1●41●129?
===================================================================================================================
?
? Beautiful answer, litb. It is a close call between yours and coppro's. Thank you! – eJames Dec 1 at 20:52?
?thanks eJames. i forgot to mention some important things though, which coppro thought about. so you did actually the right choice i think. have fun :) – litb Dec 2 at 0:00
?
===================================================================================================================
?
Use dynamic_cast for converting pointers/references within an inheritance hierarchy.
Use static_cast for ordinary type conversions.
Use reinterpret_cast for low-level reinterpreting of bit patterns. Use with extreme caution.
Use const_cast for casting away const/volatile. Avoid this unless you are stuck using a const-incorrect API.
?? answered Dec 1 at 20:22 Fred Larson 1,783●2●12
使用 dynamic_cast 在一個類繼承等級內進行轉換。
使用 static_cast 做常規類型轉換。
使用 reinterpret_cast 在底層bit模式下做轉換。使用時尤其需要小心。
使用 const_cast 去掉const/volatile。除非你需要使用無法接受const的API否則避免使用。
?? -- Fred Larson
總結
以上是生活随笔為你收集整理的When should static_cast, dynamic_cast and reinterpret_cast be used?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 60平方装修多少钱啊?
- 下一篇: 五牛图是谁画的啊?