将变量传递给派生 class 的构造函数会产生垃圾值,基础和派生 class 的构造函数都有不同的参数。为什么?
Passing variable to constructor to a derived class gives garbage value, both the base and derived class's constructors have different parameters. Why?
derived 和 base class 的构造函数都有不同的参数。
将变量传递给派生 class 的构造函数时,它在声明基数组 class 时给出了垃圾值。数组大小不是 '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);
}
散列 class 内的循环预计 运行 7 次,但在 运行ning 4 次后出现错误。
您的 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;
}
当构造函数的主体获得控制时,class 的所有非静态成员都已构造。
所以这个数据成员
LinkedList* l = new LinkedList[n];
已经使用数据成员 n 的不确定值构造。
按以下方式重写构造函数
hashing(int num) : n( num )
{
}
请注意,将 class 散列声明为 LinkedList 的派生 class 是没有意义的,因为您同时也在使用组合
好的,这里的问题很微妙(以至于我一开始没有看到问题)。
问题是您在 class 成员初始化期间使用 n (this->n
) 的值进行初始化。
问题是,在 C++ 中,那些初始化器都是 运行 在成员初始化期间,它在构造函数主体之前。由于在构造函数主体之前没有设置 this->n
的值,因此 this->n
根本没有初始化
也就是说,你有的和写的一样
hasing(int num): l(new LinkedList[n]) {
this->n = num;
}
这是因为默认情况下,所有成员都按照 class 中指定的顺序初始化,替换默认成员初始化器(class 定义中 =
之后的表达式)视情况而定。
有几种解决方案:
使用成员初始值设定项
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
最后,我会确保您正确处理销毁和 copy/move 赋值。
derived 和 base class 的构造函数都有不同的参数。
将变量传递给派生 class 的构造函数时,它在声明基数组 class 时给出了垃圾值。数组大小不是 '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);
}
散列 class 内的循环预计 运行 7 次,但在 运行ning 4 次后出现错误。
您的 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;
}
当构造函数的主体获得控制时,class 的所有非静态成员都已构造。
所以这个数据成员
LinkedList* l = new LinkedList[n];
已经使用数据成员 n 的不确定值构造。
按以下方式重写构造函数
hashing(int num) : n( num )
{
}
请注意,将 class 散列声明为 LinkedList 的派生 class 是没有意义的,因为您同时也在使用组合
好的,这里的问题很微妙(以至于我一开始没有看到问题)。
问题是您在 class 成员初始化期间使用 n (this->n
) 的值进行初始化。
问题是,在 C++ 中,那些初始化器都是 运行 在成员初始化期间,它在构造函数主体之前。由于在构造函数主体之前没有设置 this->n
的值,因此 this->n
根本没有初始化
也就是说,你有的和写的一样
hasing(int num): l(new LinkedList[n]) {
this->n = num;
}
这是因为默认情况下,所有成员都按照 class 中指定的顺序初始化,替换默认成员初始化器(class 定义中 =
之后的表达式)视情况而定。
有几种解决方案:
使用成员初始值设定项
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
最后,我会确保您正确处理销毁和 copy/move 赋值。