2008-12-14 28 views
6

मुझे अपने कार्यक्रम के लिए सूचियों का उपयोग करने की आवश्यकता है और यह तय करने की आवश्यकता है कि मैं std :: vector या std :: list का उपयोग करता हूं या नहीं। वेक्टर के साथ समस्या यह है कि कोई निकासी विधि नहीं है और सूची के साथ कोई ऑपरेटर नहीं है []। इसलिए मैंने अपनी खुद की कक्षा std :: सूची को विस्तारित करने और [] ऑपरेटर को अधिभारित करने का निर्णय लिया।विस्तारित std :: सूची

मेरे कोड इस तरह दिखता है:

#include <list> 

template <class T > 
class myList : public std::list<T> 
{ 
public: 
T operator[](int index); 
T operator[](int & index); 
myList(void); 
~myList(void); 
}; 

#include "myList.h" 

template<class T> 
myList<T>::myList(void): std::list<T>() {} 

template<class T> 
myList<T>::~myList(void) 
{ 
std::list<T>::~list(); 
} 

template<class T> 
T myList<T>::operator[](int index) { 
int count = 0; 
std::list<T>::iterator itr = this->begin(); 
while(count != index)itr++; 
return *itr;  
} 

template<class T> 
T myList<T>::operator[](int & index) { 
int count = 0; 
std::list<T>::iterator itr = this->begin(); 
while(count != index)itr++; 
return *itr; 
} 

मैं इसे संकलन कर सकते हैं लेकिन मैं एक लिंकर त्रुटि मिलती है अगर मैं इसे इस्तेमाल करने की कोशिश। कोई विचार?

+0

आप 'टी ऑपरेटर [] (पूर्णांक सूचकांक) है,' और 'टी ऑपरेटर [] (पूर्णांक और सूचकांक);' लेकिन आप कर सकते हैं 'टी एंड ऑपरेटर [] (इंट इंडेक्स) 'और' कॉन्स्ट टी एंड ऑपरेटर [] (इंट इंडेक्स) कॉन्स' का उपयोग करना चाहते हैं। साथ ही, उन कार्यों के अंदर आप गिनती का ट्रैक रखने के लिए एक नया चर बनाने के बजाय 'जबकि (अनुक्रमणिका -) 'कर सकते हैं। – Dennis

उत्तर

10

सभी टेम्पलेट कोड को हेडर फ़ाइल में रखा जाना चाहिए। इससे लिंकिंग समस्याएं ठीक हो जाती हैं (यह सबसे आसान तरीका है)। ऐसा कारण होता है क्योंकि कंपेलर अन्य स्रोतों से अलग स्रोत (.cc) फ़ाइल को संकलित करता है। दूसरी तरफ यह जानने की जरूरत है कि इसे किस कोड को बनाने की ज़रूरत है (यानी टेम्पलेट में टी को किस प्रकार से प्रतिस्थापित किया गया है), और इसका कोई अन्य तरीका नहीं है जब तक कि प्रोग्रामर इसे स्पष्ट रूप से बताए या टेम्पलेट के दौरान सभी कोड शामिल न करे तत्काल होता है। अर्थात। जब mylist.cc संकलित किया जाता है, तो यह मेरी सूची उपयोगकर्ताओं के बारे में कुछ नहीं जानता और किस कोड को बनाने की आवश्यकता है। दूसरी ओर यदि listuser.cc संकलित किया गया है, और सभी mylist कोड मौजूद है, तो संकलक आवश्यक mylist कोड बनाता है। आप here या स्ट्रॉस्ट्रप में इसके बारे में अधिक पढ़ सकते हैं।

आपके कोड में समस्याएं हैं, यदि उपयोगकर्ता नकारात्मक या बहुत बड़ा अनुरोध करता है (सूची में तत्वों की मात्रा से अधिक)। और मैं बहुत ज्यादा नहीं देखा।

इसके अलावा, मैं यू कि यह कैसे उपयोग करने की योजना पता नहीं है, लेकिन अपने ऑपरेटर [] (एन) समय है, जो शायद आसानी से हे (एन * एन) लूप को बढ़ावा मिलेगा हे है ...

+1

"आपका ऑपरेटर [] ओ (एन) समय है" - यही कारण है कि इसे मानक की 'std :: list <> 'में शामिल नहीं किया गया है। –

6

वेक्टरों में erase method है जो तत्वों को हटा सकते हैं। क्या यह पर्याप्त नहीं है?

+0

std :: list –

+0

में निकालने विधि के रूप में उपयोग करना उतना आसान नहीं है, इसके बजाय std :: remove का उपयोग करें? –

+0

इसके बारे में नहीं पता था। मैं इसे देखूंगा –

1

आपको अपने सभी टेम्पलेट कोड को हेडर में ले जाना होगा।

21

आपकी मूल समस्या कथन को देखते हुए,

मुझे अपने कार्यक्रम के लिए सूचियों का उपयोग करने की आवश्यकता है और यह तय करने की आवश्यकता है कि मैं std :: vector या std :: list का उपयोग करता हूं या नहीं। वेक्टर के साथ समस्या यह है कि कोई निकासी विधि नहीं है और सूची के साथ कोई ऑपरेटर नहीं है []।

अपनी स्वयं की सूची वर्ग (यह एक बुद्धिमान डिजाइन पसंद वैसे भी क्योंकि std::list एक आभासी नाशक है, जो एक मजबूत संकेत है कि यह एक के रूप में इस्तेमाल किया जा करने का इरादा नहीं है नहीं है नहीं है, बनाने के लिए कोई जरूरत नहीं है बेस क्लास)।

आप अभी भी std::vector और std::remove फ़ंक्शन का उपयोग करके प्राप्त कर सकते हैं। यदि v एक std::vector<T>, तो मूल्य value दूर करने के लिए है, तो आप बस लिख सकते हैं:

#include <vector> 
#include <algorithm> 
T value = ...; // whatever 
v.erase(std::remove(v.begin(), v.end(), value), v.end()); 
+0

यह होना चाहिए: v.erase (std :: हटाएं (v.begin(), v.end(), मान), vec.end()); – dalle

+0

आप सही हैं, बिल्कुल सही हैं। धन्यवाद। – ChrisN

+0

और एक एकल तत्व संस्करण: v.erase (std :: find (...)); –

1

स्पष्ट सामान पहले से ही विवरण में वर्णित किया गया है:

लेकिन तरीकों आप को लागू करने के लिए चुन ??

  • विनाशक।
    • आवश्यक नहीं संकलक आपके लिए उत्पन्न करेगा।
  • दो [] ऑपरेटर के विभिन्न संस्करणों व्यर्थ
    • इसके अलावा, आप uisng std :: सूचकांक
    • के रूप में सूची :: size_type होना चाहिए जब तक आप नकारात्मक अनुक्रमणिका का समर्थन करने का इरादा कर रहे हैं।
  • ऑपरेटर का कोई स्थिरांक संस्करणों []
  • आप लागू करने के लिए [] तुम भी पर क्या करना चाहिए जा रहे हैं()
  • आप एक सूची के निर्माण के सभी अलग अलग तरीकों से चूक गए हैं।
  • कंटेनर आंतरिक
5

अन्य उत्कृष्ट टिप्पणियों के अलावा कई प्रकार परिभाषित करना चाहिए, एक मानक कंटेनर का विस्तार करने के लिए सबसे अच्छा तरीका व्युत्पत्ति से नहीं है, लेकिन मुक्त कार्यों लेखन। उदाहरण के लिए, देखें कि Boost String Algorithms का उपयोग std::string और अन्य स्ट्रिंग कक्षाओं को बढ़ाने के लिए किया जा सकता है।

0

std :: सूची के विनाशक को कॉल करने की कोई आवश्यकता नहीं है, क्योंकि आप पहले से ही std :: सूची से प्राप्त होते हैं जब myList स्वचालित रूप से std :: सूची विनाशक के लिए बुलाया गया विनाशक कहा जाएगा।

+0

ध्यान दें कि std :: सूची में वर्चुअल विनाशक नहीं है। – gbjbaanb

+0

वर्चुअल विनाशक की कमी केवल एक समस्या होगी यदि उसने stl :: सूची में पॉइंटर के माध्यम से myList की ऑब्जेक्ट को हटाने का प्रयास किया, जो किसी भी कंटेनर का वास्तव में अजीब उपयोग होगा। –

+0

सच है, लेकिन वैसे भी याद दिलाने लायक है। – gbjbaanb

52

आपकी ज़रूरतों के आधार पर, आपको std::vector का उपयोग करना चाहिए (यदि आपको अंत में प्रायः अंतराल/यादृच्छिक पहुंच की आवश्यकता होती है), या std::deque (यदि आपको अंत में या शुरुआत में अक्सर संलग्न/हटाया जाता है, और आपका डेटासेट विशाल है, और अभी भी यादृच्छिक पहुंच चाहते हैं)। यहाँ एक अच्छा आप दिखा कैसे निर्णय करने के लिए तस्वीर है:

Container Choice http://adrinael.net/containerchoice.png

+1

यह बहुत अच्छा है, खासकर यदि आप इसे बनाने के लिए समय लेते हैं! +1 – Samaursa

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