2009-04-15 14 views
13

में सरणी आकार निर्धारित करें नीचे दिए गए कोड में मैं क्लास कन्स्ट्रक्टर कहलाते समय सरणी x की सरणी के रूप में परिभाषित करना चाहता हूं। मैं उसे कैसे कर सकता हूँ?कन्स्ट्रक्टर प्रारंभकर्ता

class Class 
{ 
public: 
    int array[]; 
    Class(int x) : ??? { } 
} 
+1

I एफ आप नियमित रूप से सी ++ का उपयोग करने की योजना बनाते हैं, मैं दृढ़ता से आपको मानक टेम्पलेट लाइब्रेरी से परिचित कराने की सलाह देता हूं। यह डेटा के संग्रह * अधिक * आसान के साथ काम करता है। – Brian

+1

एक तरफ के रूप में, वैक्टर पहले से ही आकार को जानने के बिना सरणी के साथ काम करने के लिए अपेक्षाकृत आसान बनाते हैं। आकार को पहले से जानना जरूरी नहीं है; आप push_back का उपयोग कर किसी भी तरह से वेक्टर के अंत में (amortized) ओ (1) समय के तत्वों को जोड़ सकते हैं। – Brian

+0

वेक्टरों का उपयोग करने से नई समस्याएं आती हैं, क्योंकि जिस कक्षा में मैं वेक्टरिज़ करने की कोशिश कर रहा हूं, उसने "नए" ऑपरेटरों को संरक्षित किया है। लेकिन यह वह नहीं था जिसे मैंने कभी नहीं पूछा था। – zaratustra

उत्तर

17

आप (कम से कम वर्तमान सी मानक में नहीं ++ AFAIK) एक गैर स्थिरांक आयाम के साथ एक सरणी संकलन समय पर की गणना नहीं की जा सकती है कि के आकार को प्रारंभ नहीं कर सकता।

मैं सरणी के बजाय std::vector<int> का उपयोग करने की सलाह देता हूं। यह अधिकांश संचालन के लिए वाक्यविन्यास की तरह सरणी प्रदान करता है।

+0

उस स्थिति में वेक्टर का उपयोग करने के लिए वाक्यविन्यास क्या होगा? – zaratustra

+2

वेक्टर < int > सरणी; कक्षा (एक्स): सरणी (एक्स) {}; – DevSolar

1

कच्चे सरणी का उपयोग करने के बजाय, वेक्टर का उपयोग क्यों न करें।

class SomeType { 
    vector<int> v; 
    SomeType(size_t x): v(x) {} 
}; 

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

+0

क्या आपका मतलब है "एक वेक्टर * का उपयोग * आपको स्वचालित रिसाव सुरक्षा देगा"? :) – mkb

+0

@ एमकेबी, आज दो बार मैंने मूलभूत रूप से बेवकूफ टिप्पणियां की हैं। पोस्टिंग शुरू करने से पहले जागने के लिए और अधिक कॉफी पीना चाहिए;) – JaredPar

11

नए ऑपरेटर का उपयोग करें:

class Class 
{ 
    int* array; 
    Class(int x) : array(new int[x]) {}; 
}; 
+3

अगर आप इस कोड का उपयोग करते हैं तो कन्स्ट्रक्टर में हटाएं [] को कॉल करना न भूलें। – Brian

+7

यदि आप ऐसा करते हैं तो आपको एक कॉपी कन्स्ट्रक्टर, एक असाइनमेंट ऑपरेटर और विनाशक की भी आवश्यकता होगी। एक std :: वेक्टर का उपयोग करने से आपको बिल्कुल वही कार्यक्षमता मिलती है लेकिन इनमें से कोई भी आवश्यकता नहीं होती है। –

+0

+1 यह वास्तव में एक सरणी के आकार को प्रारंभ करके ओपी के प्रश्न का उत्तर देता है, हालांकि यह वास्तव में 'int * array' को प्रतिस्थापित कर रहा है जो कि कन्स्ट्रक्टर की सूची के साथ सरणी नहीं है। @ (एनन) एक कॉपी कन्स्ट्रक्टर, एक असाइनमेंट ऑपरेटर और एक विनाशक के अलावा, यह वास्तव में सवाल का जवाब देता है। –

0

आप C++ यह नहीं कर सकते - बजाय एक std :: वेक्टर का उपयोग करें:

#include <vector> 

struct A { 
    std::vector <int> vec; 
    A(int size) : vec(size) { 
    } 
}; 
0

एक सूचक के रूप में अपने सरणी घोषित। आप बाद में शुरुआत के माध्यम से प्रारंभकर्ता सूची में इसे प्रारंभ कर सकते हैं।

अज्ञात आकार के लिए वेक्टर का उपयोग करने के लिए बेहतर।

आप this question पर और साथ ही परिवर्तनीय लंबाई सरणी देखना चाहते हैं।

+0

ज्ञात आकार के लिए वेक्टर का उपयोग करने के लिए बेहतर –

+0

को – Shree

+0

बीएडी विचार पर सहमत होना चाहिए। एक संकेतक पर स्मृति प्रबंधन करना जो सरणी की तरह कार्य करता है अपवादों की उपस्थिति में तुच्छ नहीं है। Std :: वेक्टर या std :: tr1 :: सरणी का प्रयोग करें। –

3

मुझे नहीं लगता कि यह किया जा सकता है। कम से कम जिस तरह से आप चाहते हैं। आकार गतिशील जानकारी (x) से आता है जब आप एक स्थिर आकार के सरणी (सरणी []) नहीं बना सकते हैं।

आपको या तो एक पॉइंटर-टू-इंट, और आकार स्टोर करना होगा, और प्रतिलिपि बनाने के लिए कॉपी कन्स्ट्रक्टर, असाइनमेंट ऑपरेटर और विनाशक को अधिभारित करना होगा, या std :: vector का उपयोग करना होगा।

class Class 
{ 
    ::std::vector<int> array; 
    Class(int x) : array(x) { } 
}; 
0

दो विकल्प:

उपयोग std :: वेक्टर। यह सरणी के आसान पुनः आकार बदलने की अनुमति देता है।
std :: tr1 :: array का उपयोग करें। इसका एक स्थिर आकार है।

दोनों रचनाकार प्रारंभकर्ता सूची में सही ढंग से प्रारंभ किया जा सकता है।

4

क्या आपको समझ में नहीं आता कि वेक्टर का उपयोग करने की आवश्यकता नहीं है, अगर कोई सरणी का उपयोग करना चाहता है तो यह दक्षता का विषय है, उदा। कम जगह, कोई प्रतिलिपि नहीं (ऐसे मामले में यदि सही तरीके से संभाला जाता है तो उसे विनाशक के भीतर सरणी को हटाने की भी आवश्यकता नहीं होती है), आदि। किसी भी कारण से।

सही जवाब है: (उद्धृत)

class Class 
{ 
    int* array; 
    Class(int x) : array(new int[x]) {}; 
}; 

गैर इष्टतम विकल्प का उपयोग करने के एक मजबूर करने के लिए कोशिश मत करो या आप भ्रमित अनुभवहीन प्रोग्रामर

3

इस पुराने धागे necroing के लिए खेद है हो जाएगा। वास्तव में सरणी संकलन-समय के आकार का पता लगाने का एक तरीका है।वैकल्पिक रूप से

#include <cstdlib> 

template<typename T> 
    class Class 
    { 
     T* _Buffer; 

     public: 
     template<size_t SIZE> 
      Class(T (&static_array)[SIZE]) 
      { 
       _Buffer = (T*)malloc(sizeof(T) * SIZE); 

       memcpy(_Buffer, static_array, sizeof(T) * SIZE); 
      } 

      ~Class() 
      { 
       if(_Buffer) 
       { 
        free(_Buffer); 
        _Buffer = NULL; 
       } 
      } 
    }; 

int main() 
{ 
    int int_array[32]; 
    Class<int> c = Class<int>(int_array); 

    return 0; 
} 

, यदि आप malloc/नई करने के लिए नफरत है, तो आप एक आकार टेम्प्लेटेड वर्ग के बजाय बना सकते हैं: यह कुछ इस तरह चला जाता है। हालांकि, मैं वास्तव में इसकी अनुशंसा नहीं करता और वाक्यविन्यास काफी बदसूरत है।

#include <cstdio> 

template<typename T, size_t SIZE> 
    class Class 
    { 
     private: 
      T _Array[sz]; 
     public: 
      Class(T (&static_array)[SIZE]) 
      { 
       memcpy(_Array, static_array, sizeof(T) * SIZE); 
      } 
    }; 

int main() 
{ 
    char int_array[32]; 
    Class<char, sizeof(int_array)> c = Class<char, sizeof(int_array)>(int_array); 
    return 0; 
} 

फिर भी, मुझे आशा है कि यह उपयोगी था :)

+2

के जवाब में यह केवल एक विकल्प था, आप एक विज़ार्ड – zaratustra

+0

सी ++ 11 में अंतर्निर्मित सरणी के आकार को निर्धारित करने की एक बेहतर विधि एक constexpr टेम्पलेट फ़ंक्शन का उपयोग कर रही है। उदाहरण के लिए: टेम्पलेट <कक्षा टी, std :: size_t एन> constexpr std :: size_t आकार (कॉन्स टी (और सरणी) [एन]) { वापसी एन; } – Ricky65

25

आप लोगों इसलिए इस overcomplicated है। बेशक आप इसे सी ++ में कर सकते हैं। दक्षता के लिए सामान्य सरणी का उपयोग करना उनके लिए ठीक है। एक वेक्टर केवल समझ में आता है अगर वह समय से पहले सरणी के अंतिम आकार को नहीं जानता है, यानी, इसे समय के साथ बढ़ने की जरूरत है।

आप एक स्तर उच्च सरणी आकार का पता कर सकते हैं श्रृंखला में, एक टेम्प्लेटेड वर्ग, सबसे आसान है कोई गतिशील आवंटन और मेमोरी लीक का कोई मौका नहीं है क्योंकि:

template < int ARRAY_LEN > // you can even set to a default value here of C++'11 

class MyClass 
    { 
    int array[ARRAY_LEN]; // Don't need to alloc or dealloc in structure! Works like you imagine! 
    } 

// Then you set the length of each object where you declare the object, e.g. 

MyClass<1024> instance; // But only works for constant values, i.e. known to compiler 

आपको पता नहीं कर सकते हैं उस स्थान की लंबाई जहां आप वस्तु घोषित करते हैं, या यदि आप एक ही वस्तु को अलग-अलग लंबाई के साथ पुन: उपयोग करना चाहते हैं, या आपको अज्ञात लंबाई स्वीकार करनी होगी, तो आपको इसे अपने कन्स्ट्रक्टर में आवंटित करने और इसे अपने विनाशक में मुक्त करने की आवश्यकता है ... (और सिद्धांत में हमेशा यह सुनिश्चित करने के लिए जांचें कि यह काम करता है ...)

class MyClass 
    { 
    int *array; 

    MyClass(int len) { array = calloc(sizeof(int), len); assert(array); } 
    ~MyClass() { free(array); array = NULL; } // DON'T FORGET TO FREE UP SPACE! 
    } 
संबंधित मुद्दे