将变量传递给派生 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 赋值。