6

私は 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 とは大きく異なるため、少し戸惑います。


2 番目の演習では、a) 前の Vector 実装を派生クラスとして使用し、b) Vector を構成クラスとして使用して、このようなものを実装する必要があるため、アプローチの 1 つで仮想デストラクタを使用するのではないでしょうか?

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

3 に答える 3

10

まず、なぜデストラクタが必要だと思いますvirtualか? ポリモーフィズムを使用していますか?

第二に、deleteアレイの使い方が間違っています。

あなたが使用したので:

data = new T[length];

次の配列構文を使用する必要があります。

delete [] data;

3 番目に、すべてのクラス関数定義の前に名前空間を配置する必要があります。

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

参考までに、デストラクタを次のように宣言します...

virtual ~Vector(void);

前述したように、virtualこのクラスを基本クラスまたは派生クラスとしてポリモーフィックな方法で使用しない限り、 は不要です。virtualデストラクタを使用する必要がある場合の詳細については、この質問への回答を参照してください。

またvoid、パラメータの も不要です。これは古い C 標準では必要でしたが、C++ では必要ありません。

次のように宣言できるはずです。

~Vector();

AssociativeArray<P,Q>とのhas-a関係で定義すると、Vector<T>単純にクラスに を含めることができますVector<Pair<P,Q> >。この場合、メソッドを宣言virtualする必要はありませんが、使用することはできますが、追加のオーバーヘッドが発生します。

AssociativeArray<P,Q>is-a関係で定義する場合は、デストラクタを含むいくつかのメソッドを でVector<Pair<P,Q> >定義する必要があります。virtualVector<T>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
于 2012-10-26T12:06:05.280 に答える
1

する必要があります

template <class T>
Vector<T>::~Vector() {
    delete[] data;
}
于 2012-10-26T12:05:55.067 に答える