[英]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.