派生类和基类的构造函数都有不同的参数。
当把一个变量传递给派生类的构造函数时,在声明基类的数组时,就会给出垃圾值。数组大小不是'n'而是一些垃圾值。
class LinkedList{
public:
Node* head;
LinkedList()
{
cout << "c";
head=NULL;
}
};
class hashing : public LinkedList{
public:
int n;
hashing(int num)
{
this->n=num;
}
LinkedList* l = new LinkedList[n];
void iterateL()
{
for(int i=0; i<n; i++)
{
l[i].head=NULL;
cout << i << endl;
}
}
};
int main()
{
int n=7;
hashing op(n);
}
哈希类内部的循环本应运行7次,但运行了4次后就出错了。
好吧,这里的问题很微妙(以至于我一开始没有发现问题)。
问题是你在初始化时使用了n的值(this->n
)在类内成员初始化期间运行。
问题是,在C++中,这些初始化器都是在成员初始化期间运行的,也就是在构造函数体之前。由于你没有设置 this->n
直到构造体。this->n
根本没有初始化
换句话说,你所拥有的和写的是一样的
hasing(int num): l(new LinkedList[n]) {
this->n = num;
}
出现这种情况是因为默认情况下,所有成员都是按照类中指定的顺序初始化的,用默认的成员初始化器代替(在 =
类定义中的)适当的。
有几种解决方案。
使用成员初始化器
hashing(int num): n(num),l(new LinkedList[n])
{
}
使用构造函数体。
hashing(int num)
{
this->n = num;
this->l = new LinkedList[n];
}
在上述两种情况下,我都不会设置默认的成员指定器。 我会只声明指针。
LinkedList* l; // No default member initializer
最后,我会确保你正确处理销毁,和copymove赋值。
当一个构造函数体得到控制时,类的所有非静态成员都已经被构造出来了。
所以这个数据成员
LinkedList* l = new LinkedList[n];
已经使用数据成员n的不确定值构造了。
重写构造函数的方式如下
hashing(int num) : n( num )
{
}
注意,将类hashing声明为LinkedList的派生类是没有意义的,因为同时你也在使用组成的
您的 hashing
构造函数应该是这样的。
hashing(int num)
{
this->n=num;
l = new LinkedList[n]; // allocate once 'n' is known
}
否则,你就没有在这个函数中分配足够的元素 l
. 事实上,你正在分配 n
元素,但由于 n
没有给它一个默认值,它是垃圾,和UB使用。
默认值为 l
就可以了。
LinkedList* l = nullptr;
当然,一定要删除解构器中的内存。
~hashing()
{
delete [] l;
}