2010-09-15 17 views
7

जब एक सार्वजनिक एपीआई डिजाइनिंग, यह निर्माता के रूप में स्पष्ट करने के लिए एक अच्छा अभ्यास है एक अच्छा अभ्यास है?इसे बनाने के लिए निर्माता स्पष्ट

class A { 
public: 
    //explicit A(int i){} 
    A(int i){} 
}; 

void fun(const A& a) {} 

int main() { 
    // If I use explicit for A constructor, I can prevent this mistake. 
    // (Or shall I call it as feature?) 
    fun(10); 
} 

या क्या मैं निहित रूपांतरण की अनुमति दूंगा, जिससे उपयोगकर्ता कम एपीआई को कम टाइपिंग के साथ कॉल कर सके?

उत्तर

9

निर्माता, स्पष्ट होना चाहिए, जब तक कि एक अंतर्निहित रूपांतरण शब्दार्थ समझ में आता है (उदाहरण के लिए एक A के लिए एक int परिवर्तित करने का अर्थ क्या है?)। उस निर्णय को मार्गदर्शन करने के लिए कम टाइपिंग मानदंड नहीं होना चाहिए। पठनीयता के बारे में सोचें (जो अंतर्निहित कास्टिंग के लिए मुख्य तर्क है) और आपका कोड कितना अच्छा समझना है। एक अंतर्निहित कलाकार जो अंतर्ज्ञानी नहीं है, कोड के पाठकों को उनके सिर खरोंच कर देगा।

पी.एस .: मैं एक अच्छा उदाहरण के साथ अभी आने के लिए नहीं कर पा रहे हैं, इसलिए किसी भी मदद की सराहना की है।

+7

निहित रूपांतरण के लिए उदाहरण: कुछ भी संख्या (उदा।एक बिग्नम लाइब्रेरी, या दिनांक/समय लाइब्रेरी) - निहित रूपांतरण के विरुद्ध: केवल 'std :: vector' वर्ग पर विचार करें जिसे प्रारंभिक आकार के साथ प्रारंभ किया जा सकता है। –

+1

मैं इसके साथ सहमत हूं। आईएमई शायद ही कभी ऐसा मामला है जहां आप निहित कास्टिंग चाहते हैं और यदि आप स्पष्ट पक्ष पर गलती करते हैं, तो उपयोगकर्ताओं को कुछ और कीस्ट्रोक को मजबूर कर कोई नुकसान नहीं होता है। – sbi

+0

उदाहरण के रूप में: 'जटिल (डबल रे, डबल आईएम = 0) के माध्यम से डबल से जटिल तक अंतर्निहित रूपांतरण' समझ में आता है, लेकिन 'वेक्टर (int आकार) के माध्यम से int से वेक्टर में रूपांतरण नहीं करता है। –

1

स्पष्ट कंस्ट्रक्टर्स गलती से इस तरह के वर्गों के उदाहरण बनाने के लिए उपयोगकर्ता को रोकने के लिए, वर्गों, जो महत्वपूर्ण रिसोर्सेज़ का उपभोग, स्मृति, निर्माण समय आदि की तरह किया जाता है। यह तय करने के लिए आप पर निर्भर है कि क्या आपकी कक्षा स्पष्ट कन्स्ट्रक्टर का उपयोग करने के लिए पर्याप्त "भारी" है।

+5

ऑब्जेक्टल कास्टिंग घातक हो सकता है भले ही ऑब्जेक्ट बनाने के लिए महंगा न हो। –

+0

@ Space_C0wb0y: आकस्मिक कास्टिंग गलती से एक कास्ट टाइप करने के लिए आपकी खुद की गलती है। आकस्मिक निहित रूपांतरण यहां मुद्दा है, निश्चित रूप से। –

+0

@ स्टेव जेसॉप: आप सही हैं। –

1

यह लागत शामिल पर निर्भर करता है, दोनों शब्दार्थ और प्रदर्शन। यदि आपकी कक्षा का निर्माण महंगा है तो आपको इसे तत्काल तत्काल होने से रोकना चाहिए। यदि यह बनाने के लिए एक सस्ता वर्ग है तो अंतर्निहित निर्माण एपीआई उपयोगकर्ता के लिए काम को सरल बना सकता है।

+1

यह अस्पष्टताओं और संभावित अवांछित, गैर-संवेदी रूपांतरणों का उल्लेख करने में विफल रहता है जो अन्यथा हो सकते हैं। –

4

This है एक अच्छा मौका,, क्या मैं "डैनियल Krügler"

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

+2

डैनियल क्रुगलर कौन है? –

+0

@ यान चेंग चेको: मुझे लगता है कि वह सी ++ मानकों समिति (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010) – Chubsdad

5

हां, डिफ़ॉल्ट रूप से कोई भी कन्स्ट्रक्टर, जिसे एक तर्क के साथ बुलाया जा सकता है स्पष्ट होना चाहिए। इस नियम के बाद सूक्ष्म बग से बचेंगी, जो खोजने में बेहद मुश्किल हैं।

बेशक, इस नियम के अपवाद हैं: यदि आपका वर्ग एक पैरामीटर के प्रकार के चारों ओर एक आवरण के अर्थ विज्ञान है

  • अंतर्निहित रूपांतरण, वांछनीय हो सकता है।

  • कॉपी कन्स्ट्रक्टर स्पष्ट नहीं होना चाहिए (अन्यथा आप पास-बाय-वैल्यू कॉल के लिए संभावना खो देते हैं)।

+0

+1 का हिस्सा है, लेकिन विश्वसनीयता जोड़ देगा आपने कहा कि बग कहा। –

संबंधित मुद्दे