2012-04-10 11 views
11

मैं सी ++ के लिए काफी नया हूं इसलिए यह एक मामूली सवाल हो सकता है:सी ++ में एक सरणी (वर्ग सदस्य) को सही तरीके से कैसे वापस करें?

मेरी कक्षा में एक निजी सदस्य चर है जो एक सरणी है। मुझे उस सरणी को वापस करने की ज़रूरत है, लेकिन मुझे यकीन नहीं है कि यह ठीक से कैसे करें।

class X { 
    // ... 
    private: double m_Array[9]; 
    public: double* GetArray() const { return m_Array; } 
}; 

क्या इस कोड के साथ कोई समस्या है? यह वर्ग के सदस्य को एक सूचक देता है, है ना? - इसलिए यदि मैं इस वर्ग के उदाहरण से उस सरणी को लाता हूं और इसे संशोधित करता हूं (कक्षा के बाहर से), मूल वर्ग सदस्य सरणी भी बदली जाएगी? यदि ऐसा है, तो मैं इसके बजाय सरणी की एक प्रति कैसे वापस कर सकता हूं?

+2

'std :: vector < double >' पर विचार करें यदि सरणी का आकार ठीक नहीं है (आपके उदाहरण में यह ठीक लगता है, इसलिए कोई चिंता नहीं है)। जोड़ा गया लाभ: आप वेक्टर के लिए एक संदर्भ वापस कर सकते हैं। – hochl

+2

आमतौर पर वस्तुओं के साथ आप डेटा और व्यवहार को समाहित करते हैं। क्या कोई कारण नहीं है कि आप क्या चाहते हैं 'एक्स' नहीं कर सकता? [बताओ, मत पूछो] (http://pragprog.com/articles/tell-dont-ask)। –

उत्तर

10

यह कक्षा के सदस्य को एक सूचक देता है, है ना?

लगभग - यह सरणी के पहले तत्व के लिए सूचक देता है।

अगर मैं इस वर्ग का एक उदाहरण से कि सरणी लाने और (कक्षा के बाहर से) इसे संशोधित, मूल वर्ग के सदस्य सरणी भी बदल गए हो जाएगी?

यह सही है।

यदि ऐसा है, तो मैं इसके बजाय सरणी की एक प्रति कैसे वापस कर सकता हूं?

इसे प्राप्त करने का सबसे आसान तरीका std::array या std::vector का उपयोग करना है। आपको const इसके संदर्भ में वापस लौटना चाहिए - फिर कॉलर की आवश्यकता होने पर प्रतिलिपि बनाने की लागत से बचें। उदाहरण: - जो क्या std::array है

class X { 
    std::array<double, 9> array; 
public: 
    std::array<double, 9> const & GetArray() const {return array;} 
}; 

X x; 
double d = x.GetArray()[5]; // read-only access, no copy 

auto array = x.GetArray(); // get a copy 
array[5] = 42;    // modify the copy 

या फिर, यदि सरणी एक निश्चित आकार है (क्योंकि यह आपके उदाहरण में करता है), तो आप एक सरणी एक संरचना में निहित लौट सकते हैं। अन्यथा आप एक नए आवंटित सरणी में एक सूचक (अधिमानतः एक स्मार्ट सूचक, स्मृति रिसाव से बचने के लिए) वापस कर सकते हैं - जो std::vector है या उससे कम है।

+0

हां, आपको इसे 'क्लोन' करना होगा, या किसी सरणी के मामले में, सामग्री को एक नई सरणी में कॉपी करें। –

+0

+1, लेकिन 'सरणी दृश्य' के कुछ किंड बनाने के लिए बेहतर नहीं है, जहां एक संरचना वापस आती है जो ऑपरेटर [] लागू करता है, क्योंकि मुझे लगता है कि सरणी प्रतिलिपि स्मृति और समय के बहुत से उपयोग करेगी –

+0

@YetAnotherGeek: प्रश्न पूछता है कि सरणी की एक प्रति कैसे वापस करें, इसलिए इसे मूल को प्रभावित किए बिना संशोधित किया जा सकता है। आप इसे कॉपी किए बिना ऐसा नहीं कर सकते हैं। –

2

आदेश, एक प्रति double के new सरणी की आवश्यकता होगी गतिशील आवंटित करने के लिए वापस m_Array की वर्तमान मूल्यों के साथ पॉप्युलेट और फोन करने वाले को लौट (पहला तत्व के लिए सूचक विशिष्ट होना) करने के लिए। कॉलर लौटाए गए सरणी में delete[] के लिए ज़िम्मेदार होगा। जैसा कि यह खड़ा है, कॉलर को लौटाए गए सरणी में तत्वों की संख्या का कोई ज्ञान नहीं है।

इस रूप में, सी ++ एक std::vector<double> बजाय करने के लिए बदलने का सुझाव: यह आपके लिए नकल संभालने के लिए और double रों की संख्या के बारे में जानकारी के साथ फोन करने वाले प्रदान करेगा।

2

हां, जब आप सरणी बदलते हैं तो आप कक्षा सदस्य भी बदल देंगे।

मैं आपको सी ++ में सी-स्टाइल सरणी के बजाय std :: vector का उपयोग करने की सलाह दूंगा। यह आपके जीवन को आसान बना देगा और कोड को पढ़ने में आसान बना देगा। यदि सरणी का उपयोग करने पर जोर देने का कोई कारण अभी भी है, तो आपको एक नई सरणी आवंटित करने और उसमें एक सूचक वापस करने की आवश्यकता है।ध्यान दें कि यह गतिशील स्मृति से निपटने के लिए आप के लिए मजबूर है और इसे मुक्त करने के लिए ध्यान रखना होगा:

public: 
    double* GetArray() { 
    double* res = new double[9]; 
    for (int i = 0; i < 9; ++i) { 
     res[i] = m_Array[i]; 
    } 
    return res; 
    } 

तुम भी memcpy का उपयोग सरणी के तत्वों की नकल कर सकते हैं।

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