2011-12-20 11 views
8

मैं सोच रहा था कि मेरे कोड का कौन सा हिस्सा गतिशील रूप से आवंटित होगा, लेकिन स्थैतिक वर्ग के सदस्य को अब इसकी आवश्यकता नहीं होगी। निम्नलिखित कोड देखें: classPrinter सभी A -objects के बीच साझा किया गया है और जब क्लास A का पहला उदाहरण बनाया जाएगा। बस यह सुनिश्चित करने के लिए: classPrinter - मेरे प्रोग्राम से बाहर निकलने पर ऑब्जेक्ट स्वचालित रूप से नष्ट हो जाएगा, है ना?सी ++ स्थैतिक वर्ग सदस्य, जो गड़बड़ी को साफ करता है?

a.h

class A { 
static B* classPrinter; 
} 

a.cpp

#include "a.h" 
B A::classPrinter = new B(); 

A::A() { ...} 
+3

स्मार्ट पॉइंटर्स इस तरह की चीज़ के लिए अच्छे हैं, कम से कम यदि आपको वास्तव में गतिशील आवंटन की आवश्यकता है (देखें [एसबीआई का जवाब] (http://stackoverflow.com/a/8578256/10077)। –

+1

एक .... स्थिर सूचक == बुराई –

उत्तर

19

बस यह सुनिश्चित करने के लिए: somePrinter -object मेरे प्रोग्राम से बाहर निकलने पर स्वचालित रूप से नष्ट हो जाएगा, है ना?

चूंकि यह सी ++ है, तो उत्तर "नंबर" है। new के साथ आवंटित सब कुछ के लिए संबंधित delete कहा जाना चाहिए। यदि ऐसा नहीं होता है, तो वस्तु लीक हो जाती है। लेकिन यह गतिशील रूप से आवंटित क्यों करें? यह

class A { 
    static B classPrinter; 
} 

B A::classPrinter; 

, अपने कोड की तरह बर्ताव करता सिवाय इसके कि classPrinter कार्यक्रम के अंत में विलुप्त हो जाएगा।

हालांकि, आप लिखते हैं कि

classPrinter सभी ए-वस्तुओं के बीच साझा किया और बनाई गई है जब वर्ग A का पहला उदाहरण बनाया जाएगा।

आपके प्रश्न में कोड यह नहीं करता है।

class A { 
    static std::shared_ptr<B> classPrinter; 
} 

std::shared_ptr<B> A::classPrinter; 

A::A() 
{ 
    if(!classPrinter) 
    classPrinter.reset(new B()); 
} 

स्मार्ट सूचक सुनिश्चित करें कि वस्तु हट जाता है कर देगा: यदि आप ऐसा करना चाहते हैं, कुछ इस तरह से करते हैं।

+1

"सभी ए- ऑब्जेक्ट्स और बनाया गया जब कक्षा ए का पहला उदाहरण बनाया जाएगा " – pezcode

+0

@pezcode: मुझे लगता है कि" क्लास ए का पहला उदाहरण बनाया जाएगा जब "बनाया गया है।" मैंने इसे पढ़ा, लेकिन सवाल में कोड वही करता है मेरे कोड के रूप में (निश्चित रूप से लीक करने के अलावा) – sbi

+0

नया ऑपरेटर ओवरलोड हो सकता है, मुझे लगता है कि यह कोई मामला नहीं है, लेकिन सिद्धांत रूप में यह संभव है। – Yola

3

वस्तु जिनमें से बुलाया जाएगा A::classPrinter अंक नहीं किया जा के नाशक।

यदि आप सोचते हैं कि यह तर्क के अलावा कुछ और नहीं है; delete मिलान करने वाला मिलान कहां है, सामान्य मामलों में, ऑब्जेक्ट के डीटीओ को कॉल करेगा?

कब्जा कर लिया गया स्मृति फिर से मुक्त किया जाएगा और कम से कम सभी आधुनिक में सिस्टम में लौटा दिया जाएगा।

+0

@ एसबीआई मुझे यकीन नहीं है कि मुझे आपकी टिप्पणी से पहले या बाद में मेरी पोस्ट संपादित करने का मौका मिला है, लेकिन मैंने शब्द बदल दिया है, इसलिए इसे समझना आसान होना चाहिए। –

0

यदि A::classPrinter कई सदस्यों के बीच साझा किया गया है, तो शायद कच्चे सूचक के बजाय std :: shared_ptr का उपयोग करें? इसके सभी संदर्भों के बाद इसे स्वचालित रूप से हटा दिया जाएगा।

लेकिन हाँ, स्मृति कम से कम सभी ओएस मैं के बारे में सोच सकते हैं पर, इस कार्यक्रम से बाहर निकलता है के बाद पुनः दावा किया जाएगा ...

0

आप कुछ आवरण बना सकते हैं या dtor कॉल की गारंटी करने के shared_ptr की तरह कुछ का उपयोग करने की आवश्यकता है।

10

नहीं, new का उपयोग करके बनाए गए ऑब्जेक्ट्स को स्वचालित रूप से हटाया नहीं जाता है।मेमोरी लीक को रोकने के लिए आपको हमेशा मिलान delete प्रदान करना चाहिए।

इस मामले में, सबसे सरल समाधान एक गतिशील वस्तु के लिए एक स्थिर सूचक के बजाय स्थिर वस्तु होना चाहिए - संकेत के अतिरिक्त स्तर के लिए कोई कारण नहीं है।

// header file 
class A { 
    static B classPrinter; 
}; 

// source file 
B A::classPrinter; 

या आप निर्माण में देरी जब तक वस्तु की जरूरत है (और संभावित समस्याओं से बचने यदि अन्य अनुवाद इकाइयों में स्थिर वस्तुओं उनके निर्माताओं से उस तक पहुंच की जरूरत है) करना चाहते हैं: अन्य में

class A { 
    static B & classPrinter() { 
     static B instance; 
     return instance; 
    } 
}; 

परिस्थितियों, जब आपको वास्तव में गतिशील आवंटन की आवश्यकता होती है, तो आपको हमेशा स्मार्ट पॉइंटर्स या अन्य RAII ऑब्जेक्ट्स का उपयोग करके गतिशील वस्तु का प्रबंधन करना चाहिए।

+1

वह स्थानीय स्थैतिक एक अच्छा चाल है जिसे मैं उल्लेख करना भूल गया था। मुझसे + 1' – sbi

0

स्टेटिक (जहां तक ​​स्थिर सदस्य चर) स्वाभाविक रूप से, हमेशा मौजूद है।

यदि आप एक स्थिर सूचक बनाते हैं, तो आप बस उस बिंदु पर अस्वीकार नहीं कर सकते जो समझ में आता है। आपको अधिक संदर्भ की आवश्यकता है।

यदि आप साझा डेटा चाहते हैं जो केवल तभी मौजूद है जब आपके पास स्थिर सदस्य स्वामी वर्ग के उदाहरण हों, तो आपको एक स्थिर काउंटर की आवश्यकता है। जब भी आप कोई उदाहरण बनाते हैं और काउंटर == 0. जब भी आप मालिक वर्ग के अंतिम उदाहरण को हटाते हैं तो वर्तमान स्थिर मान को आवंटित करें।

अन्यथा, आपको साझा या स्मार्ट पॉइंटर्स जैसी चीज़ों में डुबकी डालना होगा, लेकिन फिर भी आप समस्याओं में भाग लेते हैं। यदि स्मार्ट पॉइंटर कोई और संदर्भ और अस्वीकार नहीं देखता है, तो यह बहुत जल्दी हो सकता है। यदि यह अस्वीकृत राज्य में है, तो इसका मतलब क्या है जब आपको फिर से जानकारी की आवश्यकता होती है। क्या आप एक नया स्थैतिक मूल्य आवंटित करते हैं?

यदि स्थिर सदस्य को हमेशा मौजूद होना चाहिए कि आपके पास स्वामी वर्ग का उदाहरण है या नहीं, तो आपको पॉइंटर को संदर्भ या उदाहरण में बदलने पर विचार करना चाहिए।

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