static_cast
और dynamic_cast
में बहुत बड़ा अंतर नहीं है, मैं सिर्फ वस्तुओं दुनिया के लिए चर्चा कम कर देंगे।
एक static_cast
ऊपर डाली (कुख्यात) के लिए इस्तेमाल किया जा सकता है। यही कारण है:
void foo(Base& b) { Derived& d = static_cast<Derived&>(b); }
संकलक, आकलन कर सकते हैं कि क्या यह कानूनी है या नहीं क्योंकि Derived
यह की परिभाषा होने जानता है या नहीं, Derived
वास्तव में Base
के वंशज है।
गैर तुच्छ पदानुक्रम के लिए:
struct Base {};
struct D1: Base {};
struct D2: Base {};
struct Derived: D1, D2 {};
यह एक त्रुटि प्राप्त होते हैं: संकलक पता नहीं अड्डों (D1
से एक या D2
से एक आप से आया है) के रूप से।
या यदि आप virtual
विरासत का प्रयोग किया:
struct VDerived: virtual VBase {};
संकलक होगा रन-टाइम जानकारी, और इस प्रकार संकलन की जरूरत भी विफल हो जाएगा।
ए dynamic_cast
हालांकि अधिक चालाक है, हालांकि यह रनटाइम-ओवरहेड की लागत पर आता है। संकलक वस्तुओं के बारे में जानकारी उत्पन्न करता है आम तौर पर RTTI (क्रम प्रकार सूचना) के रूप में जानते हैं, कि dynamic_cast
अनुमति देने के लिए पता लगाने जाएगा:
// will throw `bad_cast` if b is not a `Derived`
void foo(Base& b) { Derived& d = dynamic_cast<Derived&>(b); }
शाखाओं करवाते हैं कास्ट:
कास्ट सच क्रम प्रकार के आधार पर
struct X {};
struct Y {};
void foo(X* x) { Y* y = dynamic_cast<Y*>(x); }
// If I add:
struct Z: X, Y {};
// then if x is in fact a Z, y will be non-null
वर्चुअल विरासत में शामिल होने पर कास्ट करें। void*
को
void bar(VBase* vb) { VDerived* vd = dynamic_cast<VDerived*>(vb); }
कास्ट (यह कुछ हद तक खास है) वस्तु का सच पता मिलता है।
void foobar(X* x)
{
void* xAddr = dynamic_cast<void*>(x);
Y* y = dynamic_cast<Y*>(y);
void* yAddr = dynamic_cast<void*>(y);
Z* z = dynamic_cast<Z*>(x);
void* zAddr = dynamic_cast<void*>(z);
if (z) { assert(xAddr == yAddr && xAddr == zAddr); }
}
नोट अगर वहाँ पदानुक्रम की वजह से एक अस्पष्टता है कि यह अभी भी काम नहीं करता है (ऊपर D1
/D2
उदाहरण में है)।