2013-03-01 7 views
5

मेरे पास एक सूची है std::list<T *> *l;। यह सूची शून्य नहीं है और इसमें कुछ मूल्य हैं। मेरी समस्या यह है कि वस्तुओं को सही तरीके से कैसे पहुंचाया जाए? मुझे सूची में पुन: प्रयास करने की आवश्यकता नहीं है। मैं सिर्फ पहले आइटम चाहता हूं।std :: सूची के पहले तत्व का उपयोग कैसे करें?

std::list<T*>::iterator it = l->begin(); 

if (it != l->end()) 
{ 
    // accessing T 
    int value = (*it)->value(); // Is this safe? 
} 

या मुझे शून्य के लिए भी जांच करनी चाहिए?

if (it != l->end() && (*it)) 
{ 
    // accessing T 
    int value = (*it)->value(); 
} 
+0

आप संकेत पकड़े, तो 'NULL' के लिए जाँच कर रहे हैं। या 'std :: सूची ' का उपयोग करें। – juanchopanza

+3

'std :: सूची ' के बजाय 'std :: list ' का उपयोग करने का निर्णय लेने के लिए आपने क्या निर्णय लिया? – LihO

+0

क्या कच्चे पॉइंटर्स का उपयोग करना वास्तव में आवश्यक है? ... –

उत्तर

8

आप std::list<T*> myList; का उपयोग करें और मान लें कि T परिभाषित किया गया है यह बताने के लिए मजबूर कर रहे हैं के रूप में:

struct T 
{ 
    T(const char* cstr) : str(cstr){ } 
    std::string str; 
}; 

तो बस पहला तत्व का उपयोग करने की std::list::front का उपयोग करें:

std::string firstStr = myList.front()->str; 

ध्यान दें कि इस मामले में myList.front() रिटर्न आपकी सूची में पहले तत्व का संदर्भ, जो इस मामले में सूचक के संदर्भ में है। तो आप इसे पहले तत्व के पॉइंटर की तरह ही इलाज कर सकते हैं।

और NULL के बारे में आपके प्रश्न के लिए: जब आप पॉइंटर्स के कंटेनर के साथ काम करते हैं, ऑब्जेक्ट को नष्ट होने के बाद पॉइंटर को कंटेनर से हटा दिया जाना चाहिए। एक बार जब आप पॉइंटर्स का उपयोग करना शुरू कर देते हैं, तो आमतौर पर इसका मतलब है कि आप वे हैं जो ऑब्जेक्ट्स से जुड़े मेमोरी मैनेजमेंट के लिए ज़िम्मेदार हो जाते हैं, जो इन पॉइंटर्स इंगित करते हैं (जो मुख्य कारण है कि आपको std::list<T>std::list<T*> से अधिक संभव होने पर हमेशा पसंद करना चाहिए)।

भी बदतर की तुलना में NULL संकेत झूलने संकेत हैं: जब आप एक वस्तु बनाने के लिए, अपने कंटेनर में अपने पते की दुकान, लेकिन एक बार वस्तु विलुप्त है, तो यह सूचक होगा आप अपने कंटेनर से इस पते को नहीं निकाला जाएगा अमान्य हो गया है और इस पॉइंटर पॉइंट्स को मेमोरी एक्सेस करने का प्रयास कर रहा है अपरिभाषित व्यवहार का उत्पादन करेगा। इसलिए न केवल आपको यह सुनिश्चित करना चाहिए कि आपके std::list में NULL पॉइंटर्स नहीं हैं, आपको यह भी सुनिश्चित करना चाहिए कि इसमें केवल वैध ऑब्जेक्ट्स के पॉइंटर्स हैं जो अभी भी मौजूद हैं।

ऐसे में उसके द्वारा आप इन तत्वों को साफ हो जाएगा, तो आप पाएंगे अपने आप को अपनी सूची से संकेतों को निकालकर और वस्तुओं वे एक ही बार में को इंगित को हटाने:

std::list<T*> myList; 

myList.push_back(new T("one")); 
myList.push_back(new T("two")); 
myList.push_back(new T("three")); 
myList.push_back(new T("four")); 

while (!myList.empty()) 
{ 
    T* pT = myList.front();      // retrieve the first element 
    myList.erase(myList.begin());    // remove it from my list 
    std::cout << pT->str.c_str() << std::endl; // print its member 
    delete pT;         // delete the object it points to 
} 

यह भी इन सवालों को पढ़ने के लिए योग्य है:
Can you remove elements from a std::list while iterating through it?
Doesn't erasing std::list::iterator invalidates the iterator and destroys the object?

+0

isnt .front वर्तमान में एक हटाए गए फ़ंक्शन नहीं है? यदि हां, तो इसके बजाय क्या उपयोग करें? – serup

0

सूची तत्व की एक अशक्त की जांच के लिए की जरूरत क्या पहली जगह में सूची में डाला जा सकता है पर पूरी तरह से निर्भर करता है।

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

+0

मैं असहमत हूं, आपको हमेशा एनयूएलएल की जांच करनी चाहिए, खासकर डेबग/विकास निर्माण में। यदि यह न्यूल होने का अनुमान नहीं है, तो अपवाद फेंक दें। –

+0

@AlexChamberlain: उस मामले में, यह भी जांचें कि सूचक अभी भी वैध, लाइव ऑब्जेक्ट को संदर्भित करता है? –

+0

अगर मैं किसी तरह से सोच सकता हूं, तो मैं डेबग बिल्ड में होगा। –

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