簡體   English   中英

在C ++中實現虛擬析構函數

[英]Implementing a virtual destructor in C++

我開始學習c ++,但我陷入了析構函數。 我們需要實現一個向量,這是我到目前為止所擁有的。

#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];
}

給出了接口,我需要實現它。 但這與C和Java有很大不同,我有點迷失。


在第二個練習中,我們需要使用a)前面的Vector實現作為派生類和b)Vector作為組合類來實現這樣的東西,所以我們可能會在其中一種方法中使用虛擬析構函數?

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;}
};

首先,為什么你認為析構函數應該是virtual 你在使用多態嗎?

其次,您正在使用不正確的數組delete

既然你用過:

data = new T[length];

您必須使用數組語法:

delete [] data;

第三,您需要將命名空間放在所有類函數定義的前面:

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

只是為了您的信息,您聲明析構函數是這樣的......

virtual ~Vector(void);

正如我所提到的, virtual是不必要的,除非您以多態方式將此類用作基類或派生類。 有關何時需要使用virtual析構函數的更多信息,請查看此問題答案

另外,參數中的void也是不必要的。 這在舊的C標准中曾經是必需的,但它不是在C ++中。

您應該可以這樣聲明它:

~Vector();

如果使用與Vector<T>has-a關系定義AssociativeArray<P,Q> ,則可以簡單地使該類包含Vector<Pair<P,Q> > 在這種情況下聲明virtual方法不是必需的,但仍然可以使用 - 帶來一些額外的開銷。

如果使用與Vector<Pair<P,Q> >is-a關系定義AssociativeArray<P,Q> ,則應在Vector<T>定義一些virtual方法,包括virtual析構函數。

virtual方法的使用僅在通過指針和引用以多態方式使用對象時才有意義。 看到這個頁面

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
template<class T> 
Vector<T>::~Vector()
{
    delete [] data;
}

請注意,您必須使用delete []而不是delete

應該

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM