Я начинаю изучать 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, что я немного растерялся.
Во втором упражнении нам нужно реализовать нечто подобное, используя а) предыдущую реализацию вектора как производный класс и б) вектор как класс композиции, поэтому, возможно, мы будем использовать виртуальный деструктор в одном из подходов?
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();
Если вы определите AssociativeArray<P,Q>
с имеет отношение к Vector<T>
, то вы можете просто сделать класс содержать Vector<Pair<P,Q> >
, декларирование virtual
методы в этом случае не нужны, но все еще могут использоваться — с некоторыми дополнительными издержками.
Если вы определите AssociativeArray<P,Q>
с это отношение к Vector<Pair<P,Q> >
тогда вы должны определить некоторые virtual
методы в Vector<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
template<class T>
Vector<T>::~Vector()
{
delete [] data;
}
Обратите внимание, что вы должны использовать delete []
и не delete
Должно быть
template <class T>
Vector<T>::~Vector() {
delete[] data;
}