संकलन समय पर जांचना संभव है। महत्वपूर्ण यह है कि है, अगर हम एक हीरे की पैटर्न:
आप स्पष्ट रूप A&
करने के लिए D&
डाली कर सकते हैं। हालांकि, अगर विरासत गैर आभासी है:
डाली अस्पष्ट होगा। तो चलो हीरा बनाने की कोशिश करो!
template <typename Base, typename Derived>
class make_diamond {
struct D2 : virtual Base { }; // this one MUST be virtual
// otherwise we'd NEVER have a diamond
public:
struct type : Derived, D2 { };
};
जो पर यह सिर्फ एक और void_t
शैली प्रकार विशेषता है इंगित:
template <typename Base, typename Derived, typename = void>
struct is_virtual_base_of : std::false_type { };
template <typename Base, typename Derived>
struct is_virtual_base_of<Base, Derived, void_t<
decltype(static_cast<Base&>(
std::declval<typename make_diamond<Base, Derived>::type&>()))
>> : std::true_type { };
तो डाली स्पष्ट है, आंशिक विशेषज्ञता में अभिव्यक्ति मान्य होगा, और कहा कि विशेषज्ञता प्राथमिकता दी जाएगी। यदि कलाकार अस्पष्ट है, तो हमारे पास प्रतिस्थापन विफलता होगी, और प्राथमिक के साथ समाप्त हो जाएगी। ध्यान दें कि Base
यहाँ वास्तव में किसी भी virtual
सदस्य कार्यों की जरूरत नहीं है:
struct A { };
struct B : public A { };
struct C : virtual A { };
std::cout << is_virtual_base_of<A, B>::value << std::endl; // 0
std::cout << is_virtual_base_of<A, C>::value << std::endl; // 1
और अगर यह किसी भी शुद्ध आभासी सदस्य कार्य करता है, हम के बाद से हम कभी नहीं वास्तव में एक वस्तु का निर्माण कर रहे हैं उन्हें ओवरराइड की जरूरत नहीं है ।
struct A2 { virtual void foo() = 0; };
struct B2 : public A2 { void foo() override { } };
struct C2 : virtual A2 { void foo() override { } };
std::cout << is_virtual_base_of<A2, B2>::value << std::endl; // 0
std::cout << is_virtual_base_of<A2, C2>::value << std::endl; // 1
बेशक
अगर अपनी कक्षा final
चिह्नित है, इस सब पर काम नहीं करेगा। लेकिन फिर, यदि यह final
था, तो इससे कोई फर्क नहीं पड़ता कि यह किस तरह की विरासत है।
अब ऐसा करने के बेहतर तरीके हो सकते हैं, लेकिन वीएस -2010 में एक माइक्रोसॉफ्ट विशिष्ट कीवर्ड है जिसे '__interface' कहा जाता है। हालांकि यह एक है) पोर्टेबल नहीं है और बी) आपको किसी कारण से सावधान रहना होगा क्योंकि इन इंटरफेस को वर्चुअल विनाशक होने की अनुमति नहीं है। – Excelcius
यह एक कार्यात्मक आवश्यकता से तकनीकी विनिर्देश की तरह लगता है। आप इसकी आवश्यकता क्यों है? –
@Excelcius हम लिनक्स के साथ ही विंडोज के लिए विकास कर रहे हैं; मैंने वीएस -2010 सूचीबद्ध किया, क्योंकि जीसीसी सी ++ 11 समर्थन में आगे है। – Angew