Pimpl मुहावरा vs शुद्ध आभासी वर्ग इंटरफ़ेस


118

मैं सोच रहा था कि पिंपल मुहावरे या शुद्ध आभासी वर्ग और विरासत को चुनने के लिए एक प्रोग्रामर क्या बनायेगा।

मैं समझता हूं कि प्रत्येक सार्वजनिक पद्धति और वस्तु निर्माण उपरि के लिए एक स्पष्ट अतिरिक्त अप्रत्यक्षता के साथ pimpl मुहावरा आता है।

दूसरे हाथ में शुद्ध आभासी वर्ग अंतर्निहित कार्यान्वयन के लिए अंतर्निहित अप्रत्यक्ष (व्यवहार्य) के साथ आता है और मैं समझता हूं कि कोई वस्तु निर्माण माथे नहीं है।
संपादित करें : लेकिन अगर आपको बाहर से वस्तु का निर्माण करना हो तो आपको एक कारखाने की आवश्यकता होगी

पिंपल मुहावरे की तुलना में शुद्ध आभासी वर्ग क्या कम वांछनीय है?


3
महान प्रश्न, बस एक ही बात पूछना चाहता था। यह भी देखें boost.org/doc/libs/1_41_0/libs/smart_ptr/sp_techniques.html
फ्रैंक

जवाबों:


60

C ++ क्लास लिखते समय, यह सोचना उचित है कि क्या होने जा रहा है

  1. एक मान प्रकार

    मूल्य से कॉपी, पहचान कभी महत्वपूर्ण नहीं होती है। यह एक std :: मानचित्र में एक कुंजी के लिए उपयुक्त है। उदाहरण, एक "स्ट्रिंग" वर्ग, या "तिथि" वर्ग, या "जटिल संख्या" वर्ग। ऐसी कक्षा के "कॉपी" उदाहरणों से समझ में आता है।

  2. एक इकाई प्रकार

    पहचान जरूरी है। हमेशा संदर्भ द्वारा पारित, "मूल्य" द्वारा कभी नहीं। अक्सर, कक्षा की "नकल" उदाहरणों के लिए बिल्कुल भी समझ में नहीं आता है। जब यह समझ में आता है, तो एक बहुरूपिक "क्लोन" विधि आमतौर पर अधिक उपयुक्त होती है। उदाहरण: एक सॉकेट क्लास, एक डेटाबेस क्लास, एक "पॉलिसी" क्लास, कुछ भी जो एक कार्यात्मक भाषा में "बंद" होगा।

दोनों pImpl और शुद्ध अमूर्त आधार वर्ग संकलन समय निर्भरता को कम करने की तकनीक है।

हालाँकि, मैं कभी भी pImpl का उपयोग मूल्य प्रकार (1 प्रकार) को लागू करने के लिए करता हूं, और केवल कभी-कभी जब मैं वास्तव में युग्मन और संकलन-समय निर्भरता को कम करना चाहता हूं। अक्सर, यह परेशान करने लायक नहीं है। जैसा कि आप ठीक से इंगित करते हैं, वहाँ अधिक सिंटैक्टिक ओवरहेड है क्योंकि आपको सभी सार्वजनिक विधियों के लिए अग्रेषण विधियों को लिखना होगा। टाइप 2 कक्षाओं के लिए, मैं हमेशा संबंधित फैक्टरी विधि (एस) के साथ एक शुद्ध सार आधार वर्ग का उपयोग करता हूं।


6
कृपया इस उत्तर के लिए पॉल डे व्रीज़ की टिप्पणी देखें । यदि आप किसी लाइब्रेरी में हैं तो पिंपल और प्योर वर्चुअल काफी भिन्न होते हैं और क्लाइंट के पुनर्निर्माण के बिना अपने .so / .dll को स्वैप करना चाहते हैं। ग्राहक नाम से पिंपल के दृश्य को जोड़ते हैं, इसलिए पुराने तरीके के हस्ताक्षर रखना पर्याप्त है। शुद्ध सार मामले में OTOH वे प्रभावी रूप से व्यवहार्य सूचकांक से लिंक करते हैं इसलिए विधियों को पुन: व्यवस्थित करने या बीच में डालने से संगतता टूट जाएगी।
स्नेक

1
द्विआधारी तुल्यता को बनाए रखने के लिए आप केवल एक पिंपल वर्ग सामने के छोर में (या फिर से आदेश) तरीके जोड़ सकते हैं। तार्किक रूप से, आपने अभी भी इंटरफ़ेस बदल दिया है और यह थोड़ा नीरस लग रहा है। यहाँ उत्तर एक समझदार संतुलन है जो "निर्भरता इंजेक्शन" के माध्यम से इकाई परीक्षण में भी मदद कर सकता है; लेकिन जवाब हमेशा आवश्यकताओं पर निर्भर करता है। थर्ड पार्टी लाइब्रेरी राइटर (अपने संगठन में लाइब्रेरी का उपयोग करने से अलग) पिम्पल को भारी पसंद कर सकते हैं।
स्पेसियन जसैट

31

Pointer to implementationआमतौर पर संरचनात्मक कार्यान्वयन विवरणों को छिपाने के बारे में है। Interfacesअलग-अलग क्रियान्वयन को प्रेरित करने के बारे में हैं। वे वास्तव में दो अलग-अलग उद्देश्यों की सेवा करते हैं।


13
जरूरी नहीं, मैंने उन कक्षाओं को देखा है जो वांछित कार्यान्वयन के आधार पर कई pimpls स्टोर करते हैं। अक्सर यह कहा जाता है कि एक win32 impl बनाम एक linux impl एक ऐसी चीज है जिसे प्रति प्लेटफॉर्म पर अलग तरीके से लागू करने की आवश्यकता है।
डग टी।

14
लेकिन आप कार्यान्वयन विवरणों को कम करने और उन्हें छिपाने के लिए एक इंटरफ़ेस का उपयोग कर सकते हैं
Arkaitz Jimenez

6
जब आप इंटरफ़ेस का उपयोग करके pimpl को कार्यान्वित कर सकते हैं, तो अक्सर कार्यान्वयन विवरणों को डिकॉप करने का कोई कारण नहीं होता है। तो बहुरूपी जाने का कोई कारण नहीं है। कारण pimpl के लिए कार्यान्वयन विवरण ग्राहक से दूर रखने के (C ++ उन्हें हैडर से बाहर रखने के) के लिए है। आप अमूर्त आधार / इंटरफ़ेस का उपयोग करके ऐसा कर सकते हैं, लेकिन आम तौर पर यह अनावश्यक ओवरकिल है।
माइकल बूर

10
यह ओवरकिल क्यों है? मेरा मतलब है, यह एक pimpl से इंटरफ़ेस विधि धीमी है? तार्किक कारण हो सकते हैं, लेकिन व्यावहारिक दृष्टिकोण से मैं इसे एक अमूर्त इंटरफ़ेस के साथ करना आसान कहूंगा
Arkaitz Jimenez

1
मैं कहूंगा कि सार आधार वर्ग / इंटरफ़ेस चीजों को करने का "सामान्य" तरीका है और
मॉकिंग के

28

पिम्पल मुहावरा विशेष रूप से बड़े अनुप्रयोगों में निर्भरता और समय को कम करने में आपकी सहायता करता है, और आपकी कक्षा के कार्यान्वयन विवरण के हेडर एक्सपोज़र को एक संकलन इकाई में कम करता है। आपकी कक्षा के उपयोगकर्ताओं को एक फुंसी के अस्तित्व के बारे में पता करने की आवश्यकता नहीं होनी चाहिए (एक गुप्त सूचक के रूप में सिवाय इसके कि वे निजी नहीं हैं!)।

अमूर्त वर्ग (शुद्ध वर्चुअल्स) ऐसा कुछ है, जिसके बारे में आपके ग्राहकों को जानकारी होनी चाहिए: यदि आप युग्मन और परिपत्र संदर्भों को कम करने के लिए उनका उपयोग करने का प्रयास करते हैं, तो आपको उन्हें अपनी वस्तुओं को बनाने की अनुमति देने के कुछ तरीके जोड़ने होंगे (जैसे कारखाना विधियों या कक्षाओं के माध्यम से,) निर्भरता इंजेक्शन या अन्य तंत्र)।


17

मैं उसी प्रश्न का उत्तर खोज रहा था। कुछ लेखों और कुछ अभ्यासों को पढ़ने के बाद मैं "शुद्ध आभासी वर्ग इंटरफेस" का उपयोग करना पसंद करता हूं

  1. वे अधिक सीधे आगे हैं (यह एक व्यक्तिपरक राय है)। पिम्पल मुहावरा मुझे लगता है कि मैं "कंपाइलर के लिए" कोड लिख रहा हूं, "अगले डेवलपर" के लिए नहीं जो मेरा कोड पढ़ेगा।
  2. कुछ परीक्षण रूपरेखाओं का मॉकिंग शुद्ध आभासी कक्षाओं के लिए प्रत्यक्ष समर्थन है
  3. यह सच है कि आपको बाहर से सुलभ होने के लिए एक कारखाने की आवश्यकता है। लेकिन अगर आप बहुरूपता का लाभ उठाना चाहते हैं: वह भी "समर्थक" है, न कि "कोन"। ... और एक साधारण फैक्टरी विधि वास्तव में इतना दर्द नहीं देती है

एकमात्र दोष ( मैं इस पर जांच करने की कोशिश कर रहा हूं ) यह है कि पिंपल मुहावरा तेज हो सकता है

  1. जब प्रॉक्सी-कॉल इनबिल्ट होते हैं, तो वंशानुक्रम के दौरान रन टाइम पर आवश्यक रूप से ऑब्जेक्ट वीटीएबल तक अतिरिक्त पहुंच की आवश्यकता होती है
  2. स्मृति पदचिह्न सार्वजनिक-छद्म वर्ग छोटा है (आप तेज स्वैप और अन्य समान अनुकूलन के लिए आसानी से अनुकूलन कर सकते हैं)

21
यह भी याद रखें कि वंशानुक्रम का उपयोग करके आप व्यवहार्य लेआउट पर निर्भरता का परिचय देते हैं। ABI को बनाए रखने के लिए आप वर्चुअल फ़ंक्शंस को नहीं बदल सकते (अंत में जोड़ना सुरक्षित है, यदि कोई बाल वर्ग नहीं है जो अपने स्वयं के वर्चुअल तरीके जोड़ते हैं)।
बजे पॉल डे व्रीज़

1
^ यह टिप्पणी यहां एक चिपचिपी होनी चाहिए।
कोडएग्री

10

मुझे पिंपल्स से नफरत है! वे कक्षा को बदसूरत और पठनीय नहीं करते हैं। सभी तरीकों को दाना करने के लिए पुनर्निर्देशित किया जाता है। आप हेडर में कभी नहीं देखते हैं कि क्या कार्यक्षमताओं की कक्षा है, इसलिए आप इसे रिफैक्ट नहीं कर सकते हैं (उदाहरण के लिए, केवल एक विधि की दृश्यता को बदलते हैं)। वर्ग "गर्भवती" की तरह महसूस करता है। मुझे लगता है कि ग्राहक से कार्यान्वयन को छिपाने के लिए पुनरावृत्तियों का उपयोग करना बेहतर और वास्तव में पर्याप्त है। आप उन्हें पतली रखने के लिए एक वर्ग को कई इंटरफेस लागू करने की अनुमति दे सकते हैं। एक इंटरफेस पसंद करना चाहिए! नोट: आपको फैक्ट्री क्लास की आवश्यकता नहीं है। प्रासंगिक यह है कि वर्ग के ग्राहक इसके साथ संवाद करते हैं, यह उपयुक्त इंटरफ़ेस के माध्यम से होता है। निजी तरीकों के छुपाने से मुझे एक अजीब व्यामोह के रूप में पता चलता है और इसका कारण नहीं दिखता क्योंकि हम हवलदार इंटरफेस करते हैं।


1
कुछ मामले हैं जब आप शुद्ध वर्चुअल इंटरफेस का उपयोग नहीं कर सकते हैं। उदाहरण के लिए जब आपके पास कुछ विरासत कोड होते हैं और आपके पास दो मॉड्यूल होते हैं जिन्हें आपको बिना छुए अलग करने की आवश्यकता होती है।
एलेक्सियनो

जैसा कि @Paul de Vrieze ने नीचे बताया है, आपने आधार वर्ग के तरीकों को बदलते समय ABI संगतता ढीली कर दी है, क्योंकि आपके पास वर्ग की व्यवहार्यता पर एक अंतर्निहित निर्भरता है। यह उपयोग के मामले पर निर्भर करता है, चाहे यह कोई समस्या हो।
एच। रिटिच

"निजी तरीकों के छिपने के कारण मुझे एक अजीब व्यामोह के रूप में पता चलता है" क्या यह आपको निर्भरता को छिपाने की अनुमति नहीं देता है और इसलिए यदि निर्भरता में बदलाव होता है तो संकलन समय को कम करना चाहिए?
पोइया 13

मुझे यह भी समझ में नहीं आ रहा है कि पिम्पल की तुलना में फैक्टरियों को फिर से फैक्टर करना कितना आसान है। क्या आप दोनों मामलों में "इंटरफ़ेस" नहीं छोड़ते हैं और कार्यान्वयन को बदलते हैं? फ़ैक्टरी में आपको एक .h और एक .cpp फ़ाइल को संशोधित करना होता है और pImpl में आपको एक .h और दो .cpp फ़ाइलों को संशोधित करना होता है, लेकिन यह इसके बारे में है और आपको आमतौर पर pImpl के इंटरफ़ेस की cpp फ़ाइल को संशोधित करने की आवश्यकता नहीं है।
पोइया 13

8

साझा पुस्तकालयों के साथ एक बहुत ही वास्तविक समस्या है कि pimpl मुहावरा बड़े करीने से शुद्ध करता है कि शुद्ध virtuals नहीं कर सकते हैं: आप अपने कोड को फिर से जमा करने के लिए वर्ग के उपयोगकर्ताओं को मजबूर किए बिना किसी वर्ग के डेटा सदस्यों को सुरक्षित रूप से संशोधित / निकाल नहीं सकते हैं। यह कुछ परिस्थितियों में स्वीकार्य हो सकता है, लेकिन सिस्टम लाइब्रेरी के लिए नहीं।

समस्या को विस्तार से समझाने के लिए, अपने साझा पुस्तकालय / शीर्ष लेख में निम्नलिखित कोड पर विचार करें:

// header
struct A
{
public:
  A();
  // more public interface, some of which uses the int below
private:
  int a;
};

// library 
A::A()
  : a(0)
{}

संकलक साझा पुस्तकालय में कोड का उत्सर्जन करता है जो पूर्णांक के पते की गणना करता है कि यह एक निश्चित ऑफसेट होने के लिए प्रारंभिक है (शायद इस मामले में शून्य है, क्योंकि यह सूचक से ए ऑब्जेक्ट के लिए एकमात्र ऐसा सदस्य है जो इसे जानता है this

कोड के उपयोगकर्ता पक्ष पर, एक new Aपहले आवंटित करेगा sizeof(A)स्मृति की बाइट्स, तो है कि स्मृति के लिए सूचक हाथ A::A()के रूप में निर्माता this

यदि आपकी लाइब्रेरी के बाद के संशोधन में आप पूर्णांक को छोड़ने का निर्णय लेते हैं, तो इसे बड़ा, छोटा, या सदस्य जोड़ें, स्मृति उपयोगकर्ता के कोड के आबंटन की मात्रा के बीच एक बेमेल होगा, और विधायक कोड की अपेक्षा करता है। संभावित परिणाम एक दुर्घटना है, यदि आप भाग्यशाली हैं - यदि आप कम भाग्यशाली हैं, तो आपका सॉफ़्टवेयर अजीब व्यवहार करता है।

पिंप्लिंग द्वारा, आप आंतरिक कक्षा में डेटा सदस्यों को सुरक्षित रूप से जोड़ और हटा सकते हैं, क्योंकि स्मृति आवंटन और कंस्ट्रक्टर कॉल साझा लाइब्रेरी में होते हैं:

// header
struct A
{
public:
  A();
  // more public interface, all of which delegates to the impl
private:
  void * impl;
};

// library 
A::A()
  : impl(new A_impl())
{}

अब आपको बस इतना करना है कि आप अपने सार्वजनिक इंटरफ़ेस को संकेतक के अलावा डेटा सदस्यों को कार्यान्वयन ऑब्जेक्ट तक मुक्त रखें, और आप त्रुटियों के इस वर्ग से सुरक्षित हैं।

संपादित करें: मुझे शायद यह जोड़ना चाहिए कि एकमात्र कारण जो मैं यहां कंस्ट्रक्टर के बारे में बात कर रहा हूं वह यह है कि मैं अधिक कोड प्रदान नहीं करना चाहता था - डेटा सदस्यों तक पहुंचने वाले सभी कार्यों पर एक ही तर्क लागू होता है।


4
शून्य * के बजाय, मुझे लगता है कि कार्यान्वयन वर्ग को आगे बढ़ाने के लिए यह अधिक पारंपरिक है:class A_impl *impl_;
फ्रैंक क्रुगर

9
मुझे समझ में नहीं आता है, आपको एक निजी शुद्ध वर्ग की घोषणा नहीं करनी चाहिए जो एक आभासी शुद्ध वर्ग में है जिसे आप एक इंटरफ़ेस के रूप में उपयोग करने का इरादा रखते हैं, विचार यह है कि कक्षा को पूरी तरह से अमूर्त, कोई आकार नहीं, केवल शुद्ध आभासी तरीकों को रखें, मुझे कुछ भी दिखाई नहीं देता है आप साझा पुस्तकालयों के माध्यम से नहीं कर सकते हैं
Arkaitz Jimenez

@ फ्रेंक क्रुगर: आप सही कह रहे हैं, मैं आलसी हो रहा था। @ अर्किट्ज़ जिमेनेज़: थोड़ा गलतफहमी; यदि आपको एक ऐसा वर्ग मिला है जिसमें केवल शुद्ध आभासी कार्य शामिल हैं, तो साझा पुस्तकालयों के बारे में बात करने में कोई मतलब नहीं है। दूसरी ओर, यदि आप साझा पुस्तकालयों के साथ काम कर रहे हैं, तो अपनी सार्वजनिक कक्षाओं को पिंपल करना ऊपर उल्लिखित कारण के लिए विवेकपूर्ण हो सकता है।

10
यह सिर्फ गलत है। दोनों विधियाँ आपको अपनी कक्षाओं के कार्यान्वयन की स्थिति को छिपाने देती हैं, यदि आप अपनी अन्य कक्षा को "शुद्ध सार आधार" वर्ग बनाते हैं।
पॉल हॉलिंगवर्थ

10
आपके aser में पहला वाक्य यह बताता है कि किसी संबंधित फ़ैक्टरी विधि के साथ शुद्ध वर्चुअल आपको किसी भी तरह से कक्षा की आंतरिक स्थिति को छिपाने की अनुमति नहीं देता है। यह सच नहीं है। दोनों तकनीकें आपको कक्षा की आंतरिक स्थिति को छिपाने देती हैं। अंतर यह है कि यह उपयोगकर्ता को कैसा दिखता है। pImpl आपको अभी भी एक वर्ग का प्रतिनिधित्व करने की अनुमति देता है जिसमें मूल्य शब्दार्थ अभी भी आंतरिक स्थिति को छिपाते हैं। शुद्ध सार बेस क्लास + फैक्टरी विधि आपको इकाई प्रकारों का प्रतिनिधित्व करने की अनुमति देता है, और आपको आंतरिक स्थिति को छिपाने की भी अनुमति देता है। बाद में ठीक है कि COM कैसे काम करता है। "एसेंशियल कॉम" के चैप्टर 1 में इस पर एक बहुत बड़ा विवाद है।
पॉल हॉलिंगवर्थ

6

हमें यह नहीं भूलना चाहिए कि प्रतिनिधिमंडल की तुलना में वंशानुक्रम एक मजबूत, घनिष्ठ युग्मन है। मैं किसी विशेष समस्या को हल करने के लिए क्या डिजाइन मुहावरों को तय करते समय दिए गए उत्तरों में उठाए गए सभी मुद्दों को भी ध्यान में रखूंगा।


3

हालांकि व्यापक रूप से अन्य उत्तरों में कवर किया गया है, हो सकता है कि मैं आभासी आधार वर्गों पर पिंपल के एक लाभ के बारे में थोड़ा और अधिक स्पष्ट हो सकता हूं:

उपयोगकर्ता दृष्टिकोण से एक pimpl दृष्टिकोण पारदर्शी है, जिसका अर्थ है कि आप उदाहरण के लिए स्टैक पर वर्ग की वस्तुओं को बना सकते हैं और उन्हें सीधे कंटेनरों में उपयोग कर सकते हैं। यदि आप अमूर्त वर्चुअल बेस क्लास का उपयोग करके कार्यान्वयन को छिपाने की कोशिश करते हैं, तो आपको एक कारखाने से बेस क्लास में एक साझा पॉइंटर को वापस करना होगा, यह उपयोग करने की जटिलता है। निम्नलिखित समकक्ष ग्राहक कोड पर विचार करें:

// Pimpl
Object pi_obj(10);
std::cout << pi_obj.SomeFun1();

std::vector<Object> objs;
objs.emplace_back(3);
objs.emplace_back(4);
objs.emplace_back(5);
for (auto& o : objs)
    std::cout << o.SomeFun1();

// Abstract Base Class
auto abc_obj = ObjectABC::CreateObject(20);
std::cout << abc_obj->SomeFun1();

std::vector<std::shared_ptr<ObjectABC>> objs2;
objs2.push_back(ObjectABC::CreateObject(13));
objs2.push_back(ObjectABC::CreateObject(14));
objs2.push_back(ObjectABC::CreateObject(15));
for (auto& o : objs2)
    std::cout << o->SomeFun1();

2

मेरी समझ में ये दोनों चीजें पूरी तरह से अलग-अलग उद्देश्य हैं। फुंसी मुहावरे का उद्देश्य मूल रूप से आपको अपने कार्यान्वयन के लिए एक संभाल देता है ताकि आप एक प्रकार के लिए तेजी से स्वैप जैसी चीजें कर सकें।

आभासी कक्षाओं का उद्देश्य बहुरूपता की अनुमति देने की रेखा के साथ अधिक है, अर्थात आपके पास एक व्युत्पन्न प्रकार की वस्तु के लिए एक अज्ञात सूचक है और जब आप फ़ंक्शन x को कॉल करते हैं तो आपको हमेशा सही फ़ंक्शन मिलता है जो आधार सूचक वास्तव में इंगित करता है।

सेब और संतरे वास्तव में।


मैं सेब / संतरे से सहमत हूं। लेकिन ऐसा लगता है कि आप एक कार्यात्मक के लिए pImpl का उपयोग करते हैं। मेरा लक्ष्य ज्यादातर निर्माण-तकनीकी और जानकारी छिपाना है।
xtofl

2

पिंपल मुहावरे के बारे में सबसे कष्टप्रद समस्या यह है कि यह मौजूदा कोड को बनाए रखने और विश्लेषण करने के लिए बहुत कठिन बनाता है। इसलिए pimpl का उपयोग करके आप डेवलपर समय और निराशा के साथ भुगतान करते हैं "बिल्ड निर्भरता और समय को कम करने और कार्यान्वयन विवरण के हेडर एक्सपोज़र को कम करने के लिए"। अपने आप को तय करें, अगर यह वास्तव में इसके लायक है।

विशेष रूप से "बिल्ड टाइम" एक ऐसी समस्या है जिसे आप बेहतर हार्डवेयर द्वारा हल कर सकते हैं या Incredibuild (www.incredibuild.com, जैसे पहले से ही विजुअल स्टूडियो 2017 में शामिल हैं) जैसे उपकरणों का उपयोग करके, इस प्रकार आपके सॉफ़्टवेयर डिज़ाइन को प्रभावित नहीं कर सकते हैं। सॉफ्टवेयर डिजाइन आमतौर पर सॉफ्टवेयर के निर्माण के तरीके से स्वतंत्र होना चाहिए।


आप डेवलपर समय के साथ भी भुगतान करते हैं जब बिल्ड समय 2 के बजाय 20 मिनट होता है, इसलिए इसका थोड़ा सा संतुलन, एक वास्तविक मॉड्यूल सिस्टम यहां बहुत मदद करेगा।
अर्काट्ज जिमेनेज

IMHO, जिस तरह से सॉफ्टवेयर बनाया गया है वह आंतरिक डिजाइन को बिल्कुल प्रभावित नहीं करना चाहिए। यह एक पूरी तरह से अलग समस्या है।
Trantor

2
क्या विश्लेषण करना मुश्किल बनाता है? Impl वर्ग को अग्रेषित करने वाली कार्यान्वयन फ़ाइल में कॉलों का एक गुच्छा कठिन नहीं लगता है।
शुभम

2
डिबगिंग कार्यान्वयन की कल्पना करें जहां पिंपल और इंटरफेस दोनों का उपयोग किया जाता है। उपयोगकर्ता कोड ए में एक कॉल से शुरू होकर, आप इंटरफ़ेस बी का पता लगाते हैं, अंत में कार्यान्वयन वर्ग डी को डीबग करना शुरू करने के लिए कूदते हुए क्लास सी पर जाते हैं ... चार चरण जब तक आप विश्लेषण नहीं कर सकते कि वास्तव में क्या होता है। और अगर पूरी बात को एक DLL में लागू किया जाता है, तो आप एक सी इंटरफ़ेस को inbetween कहीं भी खोज लेंगे।
ट्रेंटोर

आप pImpl के साथ एक इंटरफ़ेस का उपयोग क्यों करेंगे जब pImpl इंटरफ़ेस का काम भी कर सकता है? (यानी यह आपको निर्भरता को प्राप्त करने में मदद कर सकता है)
पोइयो 13
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.