जब मैं बेस क्लास घोषित करता हूं, तो क्या मुझे इसमें सभी कार्यों को आभासी के रूप में घोषित करना चाहिए, या क्या मेरे पास आभासी कार्यों का एक सेट होना चाहिए और गैर वर्चुअल फ़ंक्शंस का एक सेट होना चाहिए जो मुझे यकीन है कि विरासत में नहीं जा रहे हैं?क्या मुझे बेस वर्जन में सभी कार्यों को वर्चुअल घोषित करना चाहिए?
उत्तर
एक फ़ंक्शन केवल वर्चुअल होने की आवश्यकता है यदि एक व्युत्पन्न वर्ग उस कार्य को एक अलग तरीके से लागू करेगा।
उदाहरण के लिए:
class Base {
public:
void setI (int i) // No need for it to be virtual
{
m_i = i;
}
virtual ~Base() {} // Almost always a good idea
virtual bool isDerived1() // Is overridden - so make it virtual
{
return false;
}
private:
int m_i;
};
class Derived1 : public Base {
public:
virtual ~Derived() {}
virtual bool isDerived1() // Is overridden - so make it virtual
{
return true;
}
};
नतीजतन, मैं कुछ भी आभासी नहीं होने जब तक आप पहले से पता है कि आप इसे ओवरराइड करने का इरादा या जब तक आप है कि आप व्यवहार की आवश्यकता होती की खोज की ओर त्रुटि होगी। इसका एकमात्र अपवाद विनाशक है, जिसके लिए लगभग हमेशा यह मामला है कि आप इसे बेस क्लास में वर्चुअल होना चाहते हैं।
इंटरफ़ेस फ़ंक्शन सामान्य रूप से आभासी होना चाहिए। फ़ंक्शंस जो निश्चित कार्यक्षमता प्रदान नहीं करते हैं।
मैं केवल उन्हीं चीज़ों को बनाना चाहता हूं जो मैं अतिव्यापी वर्चुअल होना चाहता हूं। अगर मैं ओवरराइड करना चाहता हूं, तो मेरी प्रारंभिक धारणाएं गलत हो जाती हैं, मैं वापस जाता हूं और बेस क्लास बदलता हूं।
ओह, और स्पष्ट रूप से हमेशा अपने विनाशक वर्चुअल को बनाते हैं यदि आप किसी ऐसे चीज़ पर काम कर रहे हैं जो विरासत में मिलेगा।
कुछ वर्चुअल क्यों घोषित करें जब तक आप वास्तव में इसे ओवरराइड नहीं कर रहे हों? मेरा मानना है कि यह सुनिश्चित करने का सवाल नहीं है या नहीं। तथ्यों का पालन करें: क्या यह कहीं अधिक है? नहीं? फिर यह आभासी नहीं होना चाहिए।
यह एक स्थिति में परिणाम देता है जहां आप एक उप-वर्ग (एक विधि को ओवरराइड करने के लिए ओवरराइड करने के लिए) को बदलना चाहते हैं, तो आपको बेस क्लास (विधि वर्चुअल बनाने के लिए) को बदलना होगा, जिसका अर्थ है कि आपको सभी कोड को संदर्भित करना होगा जो संदर्भ बेस क्लास कुछ परियोजनाओं में बेस क्लास नाजुकता कोई समस्या नहीं है, लेकिन दूसरों में यह है। यह आपकी निर्माण प्रक्रिया पर निर्भर करता है, और इस पर कि आपने बेस क्लास इंटरफ़ेस प्रकाशित किया है या नहीं। –
तो आईएमओ विधियों को आभासी iff subclasses को ओवरराइड करने की अनुमति है (और रनटाइम बहुरूपता समर्थित है), अगर वे वास्तव में नहीं करते हैं। –
आप एक आधार वर्ग (आप यह सुनिश्चित करें कि किसी वर्ग निकला हैं) तो आप निम्नलिखित बातें कर सकते हैं बना रहे हैं:
- मेक नाशक आभासी (एक आधार वर्ग के लिए जरूरी)
- परिभाषित तरीकों व्युत्पन्न होना चाहिए और उन्हें आभासी बनाना चाहिए।
- उन विधियों को परिभाषित करें जिन्हें (नहीं होना चाहिए) गैर वर्चुअल के रूप में व्युत्पन्न किया जाना चाहिए।
- यदि फ़ंक्शंस केवल कक्षा के लिए हैं और बेस क्लास के लिए नहीं हैं तो उन्हें पर सुरक्षित रखें।
कंपाइलर नहीं जानता कि कोड का वास्तविक भाग कब चलाया जाएगा जब मूल प्रकार के सूचक वर्चुअल फ़ंक्शन को कॉल करते हैं। इसलिए कोड के वास्तविक टुकड़े को चलाने के लिए रन-टाइम पर मूल्यांकन किया जाना चाहिए, जिसके अनुसार बेस ऑब्जेक्ट पॉइंटर द्वारा ऑब्जेक्ट की ओर इशारा किया जाता है। तो वर्चुअल फ़ंक्शन के उपयोग से बचें यदि फ़ंक्शन गोन को विरासत में प्राप्त नहीं किया जाता है।
टीएलडीआर संस्करण: "आपके पास वर्चुअल फ़ंक्शंस का सेट होना चाहिए और गैर वर्चुअल फ़ंक्शंस का एक सेट होना चाहिए जो आपको यकीन है कि विरासत में नहीं जा रहे हैं।" क्योंकि वर्चुअल फ़ंक्शंस रन-टाइम पर प्रदर्शन घटता है।
आपको केवल वही कार्य करना चाहिए जो आप वर्चुअल वर्चुअल होने के लिए इच्छित हैं। एक विधि वर्चुअल बनाना रखरखाव और प्रदर्शन दोनों के मामले में मुक्त नहीं है (रखरखाव आईएमएचओ का बड़ा मुद्दा है)।
एक बार विधि आभासी होने के बाद इस विधि का उपयोग करने वाले किसी भी कोड के बारे में तर्क करना कठिन हो जाता है।क्योंकि एक विधि कॉल करने पर विचार करने के बजाय, आपको यह समझना चाहिए कि उस परिदृश्य में एन विधि कॉल क्या करेंगे। एन उस वर्ग को ओवरराइड करने वाले उप वर्गों की संख्या का प्रतिनिधित्व करता है।
इस नियम का एक अपवाद विनाशक है। वे किसी भी वर्ग में आभासी होना चाहिए जिसका उद्देश्य से लिया जाना है। यह गारंटी देने का एकमात्र तरीका है कि उचित विनाशक को विलोपन के दौरान बुलाया जाता है।
गैर-वर्चुअल इंटरफ़ेस मुहावरे (सी ++ कोडिंग मानक आइटम 39) का कहना है कि बेस क्लास में गैर वर्चुअल इंटरफ़ेस विधियां होनी चाहिए, बेस क्लास इनवेरिएंट की गारंटी दे सकती है, और बेस क्लास के अनुकूलन के लिए गैर-सार्वजनिक वर्चुअल विधियां व्युत्पन्न कक्षाओं द्वारा व्यवहार। गैर-वर्चुअल इंटरफ़ेस विधियां अतिव्यापी व्यवहार प्रदान करने के लिए वर्चुअल विधियों को कॉल करती हैं।
यहां स्रोत जोड़ने पर विचार करें। पता चला कि आप "सी ++ कोडिंग मानकों, 101 नियम, दिशानिर्देश और सर्वोत्तम अभ्यास, हर्ब सटर और Andrej Alexandrescu" का उल्लेख करते हैं। हालांकि, सी ++ में कोई आधिकारिक कोडिंग मानक नहीं है। – patrik
- 1. मुझे सी ++ में एक अमूर्त वर्ग के लिए वर्चुअल विनाशक घोषित क्यों करना चाहिए?
- 2. क्या मुझे App.xaml में कनवर्टर्स घोषित करना चाहिए या प्रति-फ़ाइल संसाधन के रूप में घोषित करना चाहिए?
- 3. मुझे "बेस :: *;" जैसे कुछ चाहिए
- 4. मुझे PHP कक्षा में चर कब घोषित करना चाहिए?
- 5. क्या मुझे सबवर्जन से परे वर्जन कंट्रोल सिस्टम देखना चाहिए?
- 6. क्या मुझे के एंड आर में सभी अभ्यास करना चाहिए?
- 7. मुझे क्या करना चाहिए?
- 8. वर्चुअल बेस क्लास डेटा सदस्य
- 9. क्या मुझे जैक्सन के ऑब्जेक्टमैपर को स्थिर क्षेत्र के रूप में घोषित करना चाहिए?
- 10. क्या मुझे मार्कडाउन को स्वच्छ करना चाहिए?
- 11. सी ++: निजी कार्यों को क्यों घोषित किया जाना चाहिए?
- 12. बाइसन/फ्लेक्स घोषणा गड़बड़ ... मुझे कैसे शामिल/घोषित करना चाहिए?
- 13. सर्वलेट कितने कार्यों को निष्पादित करना चाहिए?
- 14. com.apple.eawt - मुझे वास्तव में क्या स्थापित करना चाहिए
- 15. मुझे देखने में क्या करना चाहिए DidUnload?
- 16. मुझे पर्ल में 'स्थैतिक' सबराउटिन को कैसे परिभाषित करना चाहिए?
- 17. क्या मुझे PHP में वैश्विक कार्यों का नाम देना चाहिए?
- 18. क्या मुझे उन सभी वर्गों को सील करना चाहिए जिन्हें मुझे पता है कि कभी भी बेस क्लास के रूप में उपयोग नहीं किया जाना चाहिए?
- 19. वर्चुअल बेस क्लास के ओवरलोडेड कन्स्ट्रक्टर को कॉल करना
- 20. क्या सी ++ कक्षा में वर्चुअल स्थिर स्थिर मान घोषित करना संभव है?
- 21. मुझे खाली बेस क्लास कहां रखना चाहिए?
- 22. क्या मुझे इरनो सेट करना चाहिए?
- 23. क्या मुझे संग्रहीत मार्कडाउन को HTML में परिवर्तित करना चाहिए, या क्या मुझे बस HTML स्टोर करना चाहिए?
- 24. क्या मुझे प्राथमिक कुंजी मानों को अस्पष्ट करना चाहिए?
- 25. क्या मुझे अपना एएसपी.नेट एमवीसी नियंत्रक क्रिया वर्चुअल बनाना चाहिए?
- 26. सी ++ में, क्या मुझे लगभग हमेशा वर्चुअल विरासत का उपयोग करना चाहिए?
- 27. क्या मुझे अपने डेटाबेस में ओपनआईडी को एन्क्रिप्ट करना चाहिए?
- 28. सी ++ और जावा: वर्चुअल बेस क्लास
- 29. मुझे क्या gacutil.exe का उपयोग करना चाहिए?
- 30. क्या मुझे अपने सभी जावास्क्रिप्ट स्रोतों को एक ही फाइल में कॉपी करना चाहिए?
जब कक्षा में कम से कम एक विधि आभासी है तो आपके पास वर्चुअल विनाशक होना चाहिए। – stefanB