2012-07-04 10 views
10

मेरे पास एक सैद्धांतिक प्रश्न है, हालांकि यह एक समस्या है जिसे कभी-कभी कक्षाओं को डिजाइन करते समय सामना करना पड़ता है और मैं इसे अन्य कोड पढ़ने के दौरान अलग-अलग करता हूं। निम्न में से कौन बेहतर होगा और क्यों:क्लास डिज़ाइन: कई चर बनाम एरेज़

उदाहरण 1:

class Color 
{ 
public: 
    Color(float, float, float); 
    ~Color(); 

    friend bool operator==(Color& lhs, Color& rhs); 
    void multiply(Color); 
    // ... 
    float get_r(); 
    float get_g(); 
    float get_b(); 

private: 
    float color_values[3]; 
} 

उदाहरण 2:

class Color 
{ 
public: 
    // as above 

private: 
    float r; 
    float g; 
    float b; 
} 

वहाँ एक सामान्य नियम के एक इस तरह के मामलों में पालन करना चाहिए है या यह सिर्फ है एक प्रोग्रामर तक और क्या अधिक समझ में आता है?

+0

बीटीडब्लू क्या आपके पास खेतों को निजी रखने के लिए कोई व्यावहारिक कारण है? उदाहरण के लिए – Kos

+0

@ कोस, उदाहरण के लिए, मैं आसानी से इनपुट को प्रतिबंधित करने के लिए एक्सेसर्स और म्यूटेटर का उपयोग करके देख सकता था, हालांकि प्रत्येक फ़ील्ड शायद 'फ्लोट' के बजाय 'बाइट' होना चाहिए। इसके अतिरिक्त, '# एबीसीडीईएफ' और '# एबीसी' जैसे स्ट्रिंग मानों का उपयोग किया जा सकता है। – zzzzBov

उत्तर

4

यह निर्भर करता है, क्या आप पूरे सरणी पर फिर से प्रयास करना चाहते हैं?

उस स्थिति में, मुझे लगता है कि समाधान 1 अधिक उपयुक्त है। यह आपके लिए एक सरणी होना बहुत उपयोगी है जब आपके पास

जैसे डेटा पर लूप में काम करने वाले फ़ंक्शन हैं।

void BumpColors(float idx) 
{ 
    for (int i = 0; i < 3; ++i) 
     color_values[i] += idx; 
} 

बनाम

void BumpColors(float idx) 
{ 
    color_values[0] += idx; 
    color_values[1] += idx; 
    color_values[2] += idx; 
} 

पाठ्यक्रम के इस तुच्छ है, और मुझे लगता है कि यह वास्तव में प्राथमिकता का मामला है। कुछ दुर्लभ अवसर में आप एपीआई कि हालांकि डेटा के लिए सूचक ले हो सकता है, और जब तक आप

awesomeAPI((float*)&r); 

कर सकते हैं मैं बहुत कर रही पसंद करते हैं

awesomeAPI((float*)&color_values[0]); 

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


प्रदर्शन के अनुसार कोई अंतर नहीं होगा।

+0

पुनरावृत्ति तर्क आईएमएचओ कुंजी है, लेकिन मुझे लगता है कि रंगों के मामले में, यह दूसरी तरफ तर्क देता है। मैं ऐसे मामले के बारे में नहीं सोच सकता जहां यह एक ही मूल्य से प्रत्येक रंग को बढ़ाने के लिए समझ में आता है। –

+0

हम धारणा नहीं कर सकते कि उपयोगकर्ता रंग के साथ क्या करने जा रहा है; हम सभी जानते हैं कि वे गोलाकार-एन्कोडेड वर्टेक्स मानदंडों को संग्रहीत करने के लिए रंग वर्ग का उपयोग कर सकते हैं। –

1

क्या इस तरह के मामलों में एक सामान्य नियम का पालन करना चाहिए या यह केवल एक प्रोग्रामर तक है और क्या अधिक समझ में आता है?

यह निश्चित रूप से प्रोग्रामर तक है और जो भी अधिक समझ में आता है।

आपके मामले में, दूसरा विकल्प अधिक उपयुक्त लगता है। आखिरकार, तर्कसंगत सोचते हुए, आपका सदस्य मानों की सरणी नहीं है, लेकिन r, g और b के मान।

+0

आप किस दो विकल्पों में से "निश्चित रूप से" सहमत हैं? –

+0

@ लार्समैन हाहा - प्रोग्रामर तक और क्या अधिक समझ में आता है। –

0

एक सरणी का उपयोग कर के लाभ:

  • अनुरक्षणीयता: आप
  • अनुरक्षणीयता पाश करने के लिए सरणी में मानों का उपयोग कर सकते हैं: एक मूल्य (? तरह पीला) जोड़ा जाना चाहिए जब से आप की जरूरत नहीं है बहुत सारे कोड को बदलने के लिए।

नुकसान:

  • पठनीयता: 'मान' अधिक स्पष्ट नाम (अर्थात् आर, जी, इस मामले में ख) की है।

आपके मामले में शायद आर, जी, बी चर सबसे अच्छे हैं, क्योंकि यह संभवतः एक रंग जोड़ा नहीं गया है और 3 तत्वों पर एक लूप संभवतः पठनीयता से कम महत्व वाला है।

3

मैं कहूंगा कि दूसरा सबसे अच्छा है।

सबसे पहले, आपके चर के डेटा को एक सरणी में (भौतिक रूप से) माना जाता है। यदि आप उदाहरण के लिए 3 छात्रों के साथ एक वर्ग था, अधिक नहीं, कम नहीं, तो आप उन्हें एक सरणी में डाल देंगे, क्योंकि वे छात्रों की एक श्रृंखला हैं, लेकिन यहां, यह सिर्फ रंग हैं।

दूसरा, कोई भी जो आपके कोड को पढ़ता है, वह भी दूसरे मामले में वास्तव में तेज़ी से समझ सकता है कि आपके चर में क्या है (आर लाल है, आदि)। यह एक सरणी के साथ मामला नहीं है।

तीसरा, आपके पास कम कीड़े होंगी, आपको याद रखना होगा "ओह, मेरी सरणी में, लाल 0 है, जी 1 है, बी 2 है", और आप गलती से प्रतिस्थापित नहीं होंगे

return color_values[0] 
द्वारा

return color_values[1] 
अपने कोड में

+0

यह सच है, लेकिन दिन के अंत में यह निर्भर करता है कि वह किस रंग के लिए रंगों का उपयोग करने जा रहा है। अगर वह आरजीबी से एचएसएल में परिवर्तित करने जा रही है, जो मूल रूप से एक वेक्टर ऑपरेशन है, तो सरणी अधिक सुविधाजनक हो सकती है। इसके अलावा, एक enum के साथ सरणी को इंडेक्स करने की संभावना है, जैसे 'color_values ​​[red]' – deStrangis

+0

हाँ, मैंने enum के बारे में सोचा, लेकिन यह इतनी आसान कक्षा के लिए थोड़ा अधिक है: डी – Tuxer

+0

+1। सामान्य जेनेरिक सरणी संदर्भ द्वारा पूरी तरह से अस्पष्ट है। इसके अलावा, एक सरणी डेटा की गलत समझ को व्यक्त करती है। आर, जी, बी (कोर्स का बुरी तरह नामित) अलग-अलग चीजें हैं। वे पुनरावर्तक प्रसंस्करण में विनिमेय नहीं हैं; संदर्भ जानने के बिना उचित रूप से सेट या मूल्य प्राप्त करने का कोई तरीका नहीं है। इसलिए हम सरणी संरचना के लाभ का उपयोग नहीं कर सकते हैं। – radarbob

2

मुझे लगता है कि आप सही हैं: "यह सिर्फ एक प्रोग्रामर तक है और जो अधिक समझ में आता है।" यदि यह मेरा कार्यक्रम था, तो मैं इसके बारे में बहुत ज्यादा चिंता किए बिना एक फॉर्म या दूसरा चुनता हूं, फिर प्रोग्राम के कुछ अन्य हिस्सों को लिखता हूं, फिर बाद में इस मामले की पुनरीक्षा करता हूं।

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

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

10

दोनों!

इस का उपयोग करें:

class Color { 

    // ... 

private: 

    union { 
     struct { 
      float r, g, b; 
     }; 
     float c[3]; 
    }; 

}; 

फिर c[0]r के बराबर होगी, वगैरह।

+1

सर्वश्रेष्ठ वास्तविक उत्तर, दोनों दुनिया के सर्वश्रेष्ठ प्राप्त करें! चतुरता के लिए –

+1

+1। मैंने इस बारे में सोचा नहीं था। (भाषा मानक कानूनी रूप से, मैं 100 प्रतिशत निश्चित नहीं हूं कि यह हमेशा काम करना चाहिए, लेकिन कानूनी रूप से नहीं होने पर भी, व्यावहारिक रूप से यह काम करेगा। संकलक की कल्पना करना मुश्किल है जो आपके उत्तर को तोड़ने की संभावना है।) – thb

+0

@thb यह अच्छी तरह से परिभाषित किया गया है कि 'sizeof (the_anonymous_struct_with_the_three_floats) == 3 * आकार (फ्लोट)', जो एक पागल धारणा नहीं है। मुझे लगता है कि यदि आप पागल हैं, तो आप इसे 'static_assert' कर सकते हैं। –

0

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

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