2012-10-26 11 views
6

में वर्चुअल विनाशक को कार्यान्वित करना मैं सी ++ सीखना शुरू कर रहा हूं लेकिन मैं विनाशक में फंस गया हूं। हमें एक वेक्टर को लागू करने की जरूरत है और यही वह है जो मैंने अभी तक किया है।सी ++

#include<string.h> 
#include<cassert> 
#include<iostream> 

using namespace std; 
template<class T> 
class Vector { 
    template<class U> friend ostream& operator<<(ostream&, const Vector<U>&); 
private: 
    T* data; 
    unsigned len; 
    unsigned capacity; 
public: 
    Vector(unsigned = 10); 
    Vector(const Vector<T>&); 
    virtual ~Vector(void); 
    Vector<T>& operator =(const Vector<T>&); 
    bool operator==(const Vector<T>&); 
    T& operator[](unsigned); 
}; 

//PROBLEM! 
template <class T> 
~ Vector() { 
    delete data; 

} 

template<class T> 
Vector<T>::Vector(unsigned int _capacity) 
{ 
    capacity = _capacity; 
    len = _capacity; 
    data = new T[_capacity]; 
} 

template<class T> 
Vector<T>::Vector(const Vector<T> & v) 
{ 
    len = v.len; 
    capacity = v.capacity; 
    data = new T[len]; 
    for (unsigned int i = 0; i < len; i++) 
     data[i] = v.data[i]; 
} 



template<class T> 
Vector<T> & Vector<T>::operator = (const Vector<T> & v) 
{ 
    delete[ ] data; 
    len = v.len; 
    capacity = v.capacity; 
    data = new T [len]; 
    for (unsigned int i = 0; i < len; i++) 
     data[i] = v.data[i]; 
    return *this; 
} 

template<class T> 
bool Vector<T>::operator == (const Vector<T> & v) 
{ 
    bool check = true; 
    check &= (len == v.len); 
    if (!check) return false; 
    check &= (capacity == v.capacity); 
    if (!check) return false; 
    for (unsigned int i = 0; i < len; i++) { 
     check &= (data[i] == v.data[i]); 
     if (!check) return false; 

    } 
    return true; 
} 

template<class T> 
T& Vector<T>::operator[](unsigned int index) 
{ 
    return data[index]; 
} 

इंटरफ़ेस दिया गया है और मुझे इसे लागू करने की आवश्यकता है। लेकिन यह सी और जावा से बहुत अलग है, कि मैं थोड़ा खो गया हूँ।


दूसरा व्यायाम हम व्युत्पन्न वर्ग के रूप में इस क) पिछले वेक्टर कार्यान्वयन का उपयोग और ख) वेक्टर रचना वर्ग के रूप में है, तो शायद हम आभासी नाशक तरीकों में से एक में इस्तेमाल करेगा की तरह कुछ लागू करने की आवश्यकता में ?

void testAssociativeArray() { 
AssociativeArray<String, int> table; 
table["abc"] = 15; 
table["jkl"] = 12; 
table["xyz"] = 85; 
assert(table["jkl"], 12); 
} 

template<class P, class Q> 
class Pair { 
P p; 
Q q; public: 
     Pair(const P& _p = P(), const Q& _q = Q()): p(_p), q(_q) {} 
     P& objectP() {return p;} 
     Q& objectQ() {return q;} 
}; 
+0

बस एक ध्यान दें: आप तर्क मान द्वारा में पारित कर दिया हो रही है और "कॉपी-और-स्वैप" मुहावरा (http://stackoverflow.com/questions/3279543/ का उपयोग करके अपने 'ऑपरेटर =' सुधार कर सकते हैं क्या है-कॉपी-एंड-स्वैप-मुहावरे) –

उत्तर

10

सबसे पहले, तुम क्यों लगता है कि नाशक virtual होना चाहिए? क्या आप बहुरूपता का उपयोग कर रहे हैं?

दूसरा, आप delete का उपयोग अपनी सरणी के लिए गलत तरीके से कर रहे हैं।

जब से तुम प्रयोग किया है:

data = new T[length]; 

आप सरणी सिंटैक्स का उपयोग करना होगा:

:

delete [] data; 

तीसरा, आप अपने वर्ग समारोह परिभाषाओं के सभी के सामने नाम स्थान लगाने की जरूरत है

template <class T> 
Vector<T>::~Vector() 
{ 
    delete [] data; 
} 

और केवल अपनी जानकारी के लिए, आप इस तरह के विनाशक घोषित करते हैं ...

virtual ~Vector(void); 

मैं उल्लेख किया है, virtual अनावश्यक जब तक आप एक आधार या एक बहुरूपी ढंग से व्युत्पन्न वर्ग के रूप में इस वर्ग का उपयोग कर रहे है। virtual विध्वंसक का उपयोग करने की आवश्यकता होने पर अधिक जानकारी के लिए, answer to this question देखें।

इसके अतिरिक्त, पैरामीटर में void भी अनावश्यक है। यह पुराने सी मानक में आवश्यक था, लेकिन यह सी ++ में नहीं है।

तुम इतनी है कि यह घोषणा करने के लिए सक्षम होना चाहिए:

~Vector(); 

आप है-एक Vector<T> को संबंध है, तो आप बस वर्ग एक Vector<Pair<P,Q> > शामिल कर सकते हैं एक साथ AssociativeArray<P,Q> निर्धारित करते हैं। इस मामले में virtual विधियों की घोषणा करने की आवश्यकता नहीं है, लेकिन अभी भी उपयोग किया जा सकता है - कुछ अतिरिक्त ओवरहेड के साथ।

आपके द्वारा निर्धारित AssociativeArray<P,Q> एक साथ है-एक Vector<Pair<P,Q> > करने के लिए संबंध है, तो आप कुछ virtual तरीकों Vector<T>, एक virtual नाशक सहित परिभाषित करना चाहिए।

virtual का उपयोग केवल पॉइंटर्स और संदर्भों के माध्यम से पॉलीमोर्फिक रूप से ऑब्जेक्ट्स का उपयोग करते समय महत्वपूर्ण है। this page देखें।

AssociativeArray<String,Int>* myDerivedMap = new AssociativeArray<String,Int>(); 
delete myDerivedMap; //NO virtual methods necessary here. using a pointer to derived class 

Vector<Pair<String,Int> >* myBaseMap = new AssociativeArray<String,Int>(); 
delete myBaseMap; //virtual methods ARE necessary here. using a pointer to base class 
+0

क्या आप 'वर्चुअल'/गैर-'वर्चुअल' भाग के साथ गहराई से अधिक जा सकते हैं? – Acorbe

+1

मैं एक और प्रश्न से जुड़ा हुआ हूं जो बताता है कि एक बहुत सीधी दिशा में। –

+0

धन्यवाद। दरअसल, मैं डिजाइन के बारे में अधिक चिंतित था, यानी उसे किसी को अपने 'वेक्टर' से सुरक्षित रूप से वारिस क्यों नहीं करना चाहिए। वैसे भी, मुझे यहां अच्छे अंक मिले: http://stackoverflow.com/questions/1647298/why-dont-stl-containers-have-virtual-destructors – Acorbe

3
template<class T> 
Vector<T>::~Vector() 
{ 
    delete [] data; 
} 

ध्यान दें कि आप delete [] का उपयोग करना चाहिए और न delete

1

होना चाहिए

template <class T> 
Vector<T>::~Vector() { 
    delete[] data; 
}