2011-05-18 13 views
7

मेरे पास एक ऐसी कक्षा है जो अनजाने में गैर-प्रतिलिपि योग्य है (एक थ्रेड, इसलिए कोई प्रतिलिपि नहीं है जो समझ में आता है), और मैं इनमें से एक बड़ा 'सरणी' बनाना चाहता हूं, जैसा कि समान रूप से बनाया गया है गैर-डिफ़ॉल्ट कन्स्ट्रक्टर। ध्यान दें कि सरणी निश्चित आकार है।noncopyable ऑब्जेक्ट्स के "सरणी" का निर्माण

मैं केवल सी ++ सरणी के साथ डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग कर सकता हूं, जब तक कि मैं प्रत्येक को स्वतंत्र रूप से प्रारंभ नहीं करता।

Thread myArray[128]; // uses default constructor - wrong 

मैं स्पष्ट रूप से वस्तु निर्माणकर्ता और मानकों को सूचीबद्ध कर सकते हैं, लेकिन यह अत्यधिक शब्द और बदसूरत

Thread myArray[128] = { Thread(params,...), Thread(params,...), ... x 128 ; // ugly 

ऐसा लगता है मैं STL वैक्टर का उपयोग नहीं कर सकते क्योंकि वस्तु गैर copyable है - हालांकि वेक्टर घटना आकार कभी नहीं बदलता है। मुझे लगता है कि निर्माता वास्तव में नकल करता है!

std::vector<Thread> myVector(128, Thread(params,...));// won't compile 

तरह से मैं हालांकि ऐसा करने का है स्मार्ट संकेत की एक सरणी और एक प्रारंभ पाश के साथ है, लेकिन कुछ शायद मैं याद कर रहा हूँ:

क्या कोई अन्य रास्ता नहीं है - हो सकता है बढ़ावा कंटेनर के साथ , या एक अलग कंटेनर प्रकार?

+3

स्मार्ट-पॉइंटर का उपयोग करने के लिए समझदार चीज़ की तरह लगता है। मुझे नहीं लगता कि एक बेहतर तरीका है। –

+1

यदि वे "समान रूप से निर्मित" हैं, तो क्या आप एक डिफ़ॉल्ट कन्स्ट्रक्टर नहीं जोड़ सकते हैं जो ऐसा करता है? अन्यथा @ Space_C0wb0y के साथ जाएं। –

+0

क्यूटी लाइब्रेरी एक बहुत प्रसिद्ध लाइब्रेरी है, और वे पॉइंटर्स के साथ गैर कॉपी करने योग्य ऑब्जेक्ट्स (जीयूआई विजेट, पूरी तरह से कॉपी करने योग्य) के सरणी संभालती हैं। तो मुझे लगता है कि स्मार्ट पॉइंटर्स जाने का रास्ता हैं। – Fezvez

उत्तर

3

प्रत्येक पॉइंट गतिशील रूप से आवंटित स्मार्ट पॉइंटर्स का एक वेक्टर, निश्चित रूप से सबसे सरल तरीका है। अन्यथा (और मैं केवल तभी ऐसा कर सकता हूं जब आप पूरी तरह से आवश्यक हों), आप अनुकरण कर सकते हैं कि std::vector आंतरिक रूप से क्या करता है। की पंक्तियों के साथ कुछ:

union 
{ 
    double just_to_ensure_alignment; 
    unsigned char data[ sizeof(Thread) * elementCount ]; 
} array; 

// construct... 
for (int i = 0; i != elementCount; ++ i) 
    new (data + i * sizeof(Thread)) Thread(params,...); 

// access... 
Thread& getAt(int i) 
{ 
    return reinterpret_cast<Thread*>(data + i * sizeof(Thread)); 
} 

समर्थन आर-मूल्य (मैं वास्तव में इस एक कक्षा में लपेट चाहते हैं, यदि केवल getAt के बजाय operator[] उपयोग करने के लिए सक्षम होने के लिए।)

+0

धन्यवाद। मैं बूस्ट की एक सरणी का उपयोग कर समाप्त हुआ :: shared_ptr – Roddy

6

यह पूरी तरह पागल की तरह लग सकता है (और यह शायद है), लेकिन ...

struct ThreadInitValues{ 
    // your actual params 
    int i; 
    float f; 
}; 

struct Thread{ 
    Thread(int i = _init.i, float f = _init.f) 
     : _i(i) 
     , _f(f) 
    {} 

    static ThreadInitValues _init; 

private: 
    // uncopyable 
    Thread(Thread const&); 
    Thread& operator=(Thread const& other); 

    // your actual member 
    int _i; 
    float _f; 
}; 

ThreadInitValues Thread::_init; 

int main(){ 
    Thread::_init.i = 5; 
    Thread::_init.f = 3.14f; 
    Thread arr[128]; 
} 

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

+5

पागल के लिए +1। लेकिन मुझे लगता है कि स्मार्ट पॉइंटर्स की सरणी अधिक मूर्खतापूर्ण है, और पढ़ने में आसान है। – Roddy

1

नई compilers के लिए संदर्भ, प्रतिलिपि होने के नाते वेक्टर तत्व AFAIK के लिए आवश्यक नहीं है। 128 push_back की प्रतिलिपि किए बिना इसका उपयोग करने के लिए उपयोग किया जाना चाहिए (प्रत्येक बार नई वस्तु बनाना), क्योंकि एक ही से कई ऑब्जेक्ट्स को क्रिएट करना एक प्रतिलिपि है :)।

यदि यह तरीका उपलब्ध नहीं है, तो boost::ptr_vector या std :: vector of boost :: shared_ptr आज़माएं।

+0

सावधान रहें: एमएसवीसी नकली सीटीआर पर प्रतिलिपि ctor तक पहुंचने की कोशिश करता है भले ही इसे चाल ctor – Xeo

+0

हम्म तक पहुंचाया जाए। लेकिन 'myVector नहीं होगा (128, थ्रेड (पैरा, ...))' कन्स्ट्रक्टर को अभी भी प्रतिलिपि करने की आवश्यकता है? आखिरकार, मैं केवल एक ऑब्जेक्ट में गुजर रहा हूं और मुझे 128 बनाया गया है ... – Roddy

+0

मैंने उत्तर अपडेट किया है - बस push_back का उपयोग करें। – maxim1000

0

मैं इतना बड़ा प्रोग्रामर नहीं हूं। लेकिन क्या आपने यह

std::vector<YourObject *> temp_Vec; 
for(int i=0;i<128;++i) 
    temp_Vec.push_back(new YourObject(arguments)); 
+1

स्मार्ट पॉइंटर्स अधिक सुरक्षित होंगे। बढ़ावा :: scoped_ptr, उदाहरण के लिए। – Roddy

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