2008-11-21 15 views
42

क्या यह सभी निजी सदस्यों, फिर सभी संरक्षित लोगों, तो सभी सार्वजनिक लोगों के लिए बेहतर है? या विपरीत? या क्या कई निजी, संरक्षित और सार्वजनिक लेबल होना चाहिए ताकि संचालन कन्स्ट्रक्टर से अलग रखा जा सके और इसी तरह? यह निर्णय लेने पर मुझे किन मुद्दों पर ध्यान देना चाहिए?मुझे सी ++ कक्षा के सदस्यों को कैसे आदेश देना चाहिए?

+1

यह देखना दिलचस्प है कि इस तरह के लगभग पूरी तरह से राय-आधारित धागे को 'दिन में वापस' कैसे गर्म किया गया था, जबकि मुझे लगता है और उम्मीद है कि उन्हें आजकल विस्मरण में ध्वजांकित किया जाएगा। –

उत्तर

7

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

2

मुझे लगता है कि यह सब पठनीयता के बारे में है।

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

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

यह सामान है जो बड़ी परियोजनाओं के कोडिंग मानकों द्वारा कवर किया जा सकता है, यह जांचना एक अच्छा विचार हो सकता है।

-3

पूरी तरह से आपकी वरीयता पर निर्भर करता है। कोई "सही रास्ता" नहीं है।

अपनी पालतू परियोजनाओं में सी ++ करते समय मैं व्यक्तिगत रूप से सम्मेलन करता हूं कि मैंने प्रत्येक सदस्य या विधि घोषणा से पहले एक्सेस संशोधक रखा है।

+0

मैंने आपको चिह्नित नहीं किया लेकिन मुझे संदेह है कि कुछ ने ऐसा किया क्योंकि प्रत्येक सदस्य के सामने एक एक्सेस संशोधक डालना अनावश्यक और अति-शीर्ष है। स्पष्ट रूप से मुझे लगता है कि यह अतिरिक्त शोर के कारण सुगमता को प्रभावित करता है। – MattyT

+2

यह आपके सी ++ जावा की तरह दिखता है। सवाल यह है कि क्या जावा का "प्रति घोषणा एक अतिरिक्त शब्द टाइप करें" सी ++ के "एक्सेस विनिर्देशक वैश्विक राज्य को बदलते हैं, जो प्रत्येक घोषणा द्वारा स्पष्ट रूप से उपयोग किया जाता है" से बेहतर या बदतर है। अगर आप जावा पसंद करते हैं तो भी आपको सी ++ में सी ++ तरीका करना चाहिए। –

+0

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

43

मैंने पहले सार्वजनिक इंटरफेस लगाया, लेकिन मैंने हमेशा ऐसा नहीं किया। मैं निजी, फिर संरक्षित, फिर सार्वजनिक के साथ, पीछे की ओर चीजें करता था। वापस देखकर, यह बहुत समझ में नहीं आया।

एक कक्षा के डेवलपर के रूप में, आप शायद अपने "अंदरूनी" से परिचित होंगे लेकिन कक्षा के उपयोगकर्ताओं को ज्यादा परवाह नहीं है, या कम से कम उन्हें नहीं करना चाहिए। वे ज्यादातर रुचि रखते हैं कि कक्षा उनके लिए क्या कर सकती है, है ना?

इसलिए मैंने जनता को पहले रखा, और इसे आम तौर पर कार्य/उपयोगिता द्वारा व्यवस्थित किया। मैं नहीं चाहता कि उन्हें एक्स से संबंधित सभी विधियों को ढूंढने के लिए मेरे इंटरफ़ेस से गुजरना पड़े, मैं चाहता हूं कि वे एक साथ व्यवस्थित तरीके से उन सभी चीजों को एक साथ देखें।

मैं कभी भी कई सार्वजनिक/संरक्षित/निजी वर्गों का उपयोग नहीं करता - मेरी राय में पालन करने के लिए भी भ्रमित है।

+0

यह केवल मेरी राय है, लेकिन मैं इस बात से सहमत नहीं हूं कि कक्षा के उपयोगकर्ताओं को अंदरूनी लोगों की परवाह नहीं करनी चाहिए। मुझे लगता है कि उपयोगकर्ताओं को परवाह करना चाहिए, क्योंकि अमूर्तता और encapsulation केवल जटिल समस्याओं का सामना करने की अनुमति देने के लिए है और उपयोगकर्ताओं को विवरण से निपटने के लिए मुक्त नहीं है। –

+5

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

+0

@itsmatt sizeof (ऑब्जेक्ट) सदस्यों के आदेश पर निर्भर करता है अगर मुझे गलत नहीं लगता है। यदि ऐसा है तो इसका आदेश पर असर नहीं पड़ता है? मान लीजिए कि मेरे पास निजी और साथ ही सार्वजनिक और फिर अन्य चार प्रकार के चर में एक डबल है, क्या मुझे दोहरे चर को एक साथ रखने की ज़रूरत है? ऐसे मामले में हम कैसे संभालते हैं? – Rajesh

29

Google this order का समर्थन करता है: "स्थिर डेटा सदस्यों सहित स्थिर तरीकों, डेटा सदस्यों सहित टाइपपीफ और एनम्स, कॉन्स्टेंट, कंस्ट्रक्टर, विनाशक, तरीके।"

Matthew Wilson (सफारी सदस्यता आवश्यक) निम्नलिखित आदेश की सिफारिश करता है: "निर्माण, संचालन, गुण, परिवर्तन, राज्य, कार्यान्वयन, सदस्य, और मेरा पसंदीदा, लागू नहीं किया जाना चाहिए।"

वे अच्छे कारण प्रदान करते हैं, और इस तरह का दृष्टिकोण काफी मानक लगता है, लेकिन जो कुछ भी आप करते हैं, उसके बारे में सुसंगत रहें।

4

मैं आमतौर पर पहले इंटरफ़ेस (पढ़ने के लिए) परिभाषित करता हूं, जो सार्वजनिक है, फिर सुरक्षित है, फिर निजी सामान। अब, कई मामलों में मैं एक कदम आगे जाता हूं और (यदि मैं इसे संभाल सकता हूं) PIMPL पैटर्न का उपयोग करें, वास्तविक वर्ग के इंटरफ़ेस से सभी निजी सामानों को पूरी तरह छुपाएं।

class Example1 { 
public: 
    void publicOperation(); 
private: 
    void privateOperation1_(); 
    void privateOperation2_(); 

    Type1 data1_; 
    Type2 data2_; 
}; 
// example 2 header: 
class Example2 { 
    class Impl; 
public: 
    void publicOperation(); 
private: 
    std::auto_ptr<Example2Impl> impl_; 
}; 
// example2 cpp: 
class Example2::Impl 
{ 
public: 
    void privateOperation1(); 
    void privateOperation2(); 
private: // or public if Example2 needs access, or private + friendship: 
    Type1 data1_; 
    Type2 data2_; 
}; 

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

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

0

हमारी परियोजना में, हम सदस्यों के उपयोग के अनुसार आदेश नहीं देते हैं, लेकिन उपयोग के द्वारा। और इसके द्वारा मेरा मतलब है, हम सदस्यों का आदेश देते हैं क्योंकि उनका उपयोग किया जाता है। एक सार्वजनिक सदस्य एक ही कक्षा में एक निजी सदस्य का उपयोग करता है, तो है कि निजी सदस्य आमतौर पर सार्वजनिक सदस्य के सामने कहीं निम्नलिखित (सरलीकृत) उदाहरण के रूप में स्थित है,:

class Foo 
{ 
private: 
    int bar; 

public: 
    int GetBar() const 
    { 
    return bar; 
    } 
}; 
यहाँ

, सदस्य बार सदस्य गेटबार() से पहले रखा गया है क्योंकि पूर्व का उपयोग बाद वाले द्वारा किया जाता है। यह, मल्टीपल एक्सेस वर्गों में परिणाम कर सकते हैं निम्न उदाहरण में:

class Foo 
{ 
public: 
    typedef int bar_type; 

private: 
    bar_type bar; 

public: 
    bar_type GetBar() const 
    { 
    return bar; 
    } 
}; 

bar_type सदस्य बार सदस्य द्वारा प्रयोग किया जाता है, देखते हैं?

ऐसा क्यों है? मुझे पता नहीं, यह और अधिक स्वाभाविक प्रतीत होता है कि यदि आप कार्यान्वयन में किसी सदस्य का सामना करते हैं और आपको इसके बारे में अधिक जानकारी चाहिए (और इंटेलिसेन्स फिर से खराब हो गया है) कि आप इसे कहीं से ऊपर कहीं से ढूंढ सकते हैं।

1

यह उन लोगों के लिए वास्तव में उपयोगी है जो आपकी कक्षा का उपयोग सार्वजनिक इंटरफ़ेस को पहले सूचीबद्ध करने के लिए करेंगे। यह वह हिस्सा है जिसकी वे परवाह करते हैं और इसका उपयोग कर सकते हैं। संरक्षित और निजी के बाद के साथ पालन कर सकते हैं।

सार्वजनिक इंटरफ़ेस के भीतर, समूह समूहों, संपत्ति एक्सेसर्स और म्यूटेटर समूह और ऑपरेटरों को अलग-अलग समूहों में सुविधाजनक बनाना सुविधाजनक है।

4

हमेशा के रूप में, मनुष्यों के लिए अपना कोड लिखें। उस व्यक्ति पर विचार करें जो आपकी कक्षा का उपयोग करेगा और शीर्ष पर पर सबसे महत्वपूर्ण सदस्यों/enums/typedefs/जो भी रखेगा।

आमतौर पर इसका मतलब है कि सार्वजनिक सदस्य शीर्ष पर हैं क्योंकि आपकी कक्षा के अधिकांश उपभोक्ता सबसे अधिक रुचि रखते हैं। संरक्षित अगले के बाद निजी होते हैं। आम तौर पर।

कुछ अपवाद हैं।

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

लेकिन वे अपेक्षाकृत दुर्लभ परिस्थितियां हैं।

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

लेकिन उपभोक्ता पर ब्याज द्वारा ऑर्डर करके ऑर्डर करके और के बारे में अधिक जानकारी देने के बारे में यह कम है।

1

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

यह भी विचार है कि आपको स्मृति संरेखण के कारण बर्बाद जगह से बचने के लिए कक्षा के सदस्यों को आदेश देना चाहिए; एक रणनीति सदस्यों को सबसे छोटे से बड़े आकार के आदेश देने के लिए है। मैंने कभी भी सी ++ या सी में ऐसा नहीं किया है।

+0

मेरा मानना ​​है कि सिफारिश वास्तव में सबसे छोटी से सबसे छोटी है, है ना? मुझे फिर से देखना होगा, शायद हम एक संदर्भ पा सकते हैं। –

+0

[यहां] (http://stackoverflow.com/a/894032/557981) आदेश बनाम संरेखण के लिए अच्छा जवाब है। –

0

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

उसमें, सदस्य प्रकार और स्थिरांक सबसे पहले सबसे अच्छे हैं, इसके बाद निर्माण ऑपरेटर, संचालन, और उसके बाद सदस्य चर।

1

प्रैक्टिस में, यह शायद ही कभी मायने रखता है। यह मुख्य रूप से व्यक्तिगत वरीयता का मामला है।

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

यह है, अगर वे वर्ग को संशोधित कर रहे हैं लोगों को अपने हेडर में होने के लिए और अधिक संभावना है जो मामले में वे चाहिए निजी इंटरफ़ेस के बारे में देखभाल।

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

-1

निजी फ़ील्ड को पहले रखें।

आधुनिक आईडीई के साथ, लोग इस बात को समझने के लिए कक्षा नहीं पढ़ते कि यह सार्वजनिक इंटरफ़ेस क्या है।

वे इसके लिए इंटेलिजेंस (या क्लास ब्राउज़र) का उपयोग करते हैं।

यदि कोई वर्ग परिभाषा के माध्यम से पढ़ रहा है, तो आमतौर पर यह समझना है कि यह कैसे काम करता है।

उस स्थिति में, फ़ील्ड को जानना सबसे अधिक मदद करता है। यह आपको बताता है कि वस्तु के कुछ हिस्सों क्या हैं।

+0

मैं डब्ल्यू/योग्यता से सहमत हो सकता हूं लेकिन सॉर्टा समझता हूं कि यह क्यों कम किया गया था ... ऐसा नहीं कहा कि मतदाताओं ने समस्या की व्याख्या करने के लिए निंदा की। _Qualifications_: मेरे उपयोग के लिए कक्षाओं को कोड करते समय, मैं ऐसा कुछ करता हूं: निजी फ़ील्ड्स शीर्ष पर, फिर निजी फ़ंक्शन; फिर नीचे सार्वजनिक सामान। निर्भरता आदेश देने के लिए स्पष्ट रूप से समायोजन। और मैं एक आईडीई का भी उपयोग नहीं करता, बस 'vim'! लेकिन वहां _Problem_ है: क्या मैं दूसरों के उपयोग के लिए कक्षाएं लिख रहा था, मैं उनके साथ दिमाग में लिखूंगा, यानी।सामने सबसे प्रासंगिक चीजों के साथ। यह सिर्फ विनम्र है, esp अगर वे भी जो भी आईडीई वर्तमान में प्रचलित है उसे छोड़ दें –

0

कोडिंग शैली आश्चर्यजनक रूप से गर्म बातचीत के लिए एक स्रोत है, जो मन में मैं एक अलग राय प्रदान करने का जोखिम के साथ:

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

विचलन वह रोल है जिसे हम ले रहे हैं।

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

हालांकि, कोई है जो करने की जरूरत है समझ में कोड, कोड की समीक्षा के दौरान, अनुरोध, या रखरखाव खींच लिए, क्रम में एक महान सौदा मायने रखती है - नियम सरल है:

आइटम वे पहले परिभाषित किया जाना चाहिए

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

निजी बनाम सख्ती से एक विभाजन बनाना। सार्वजनिक इस नियम का उल्लंघन करता है क्योंकि किसी भी सार्वजनिक विधि में उपयोग किए जाने के बाद निजी वर्ग के सदस्य दिखाई देंगे।

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