我开始学习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;} };
解决方法
首先,为什么你认为析构函数应该是虚拟的?你在使用多态吗?
其次,您正在使用不正确的数组删除.
既然你用过:
data = new T[length];
您必须使用数组语法:
delete [] data;
第三,您需要将命名空间放在所有类函数定义的前面:
template <class T> Vector<T>::~Vector() { delete [] data; }
只是为了您的信息,您声明析构函数是这样的……
virtual ~Vector(void);
正如我所提到的,虚拟是不必要的,除非您以多态方式将此类用作基类或派生类.有关何时需要使用虚拟析构函数的更多信息,请查看answer to this question.
另外,参数中的空隙也是不必要的.这在旧C标准中曾经是必需的,但它不在C中.
您应该可以这样声明它:
~Vector();
如果您定义AssociativeArray< P,Q>通过与Vector< T>的has-a关系,你可以简单地使该类包含Vector< Pair< P,Q>取代.在这种情况下声明虚拟方法不是必需的,但仍然可以使用 – 带来一些额外的开销.
如果您定义AssociativeArray< P,Q>具有与Vector< Pair< P,Q>的关系的is-a. >,然后您应该在Vector< T>中定义一些虚拟方法,包括虚拟析构函数.
虚拟方法的使用仅在通过指针和引用以多态方式使用对象时才有意义.见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