将变量传递给构造函数到派生类,会给出垃圾值,基类和派生类的构造函数都有不同的参数。为什么呢?

问题描述 投票:0回答:1

派生类和基类的构造函数都有不同的参数。

当把一个变量传递给派生类的构造函数时,在声明基类的数组时,就会给出垃圾值。数组大小不是'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次后就出错了。

c++ oop constructor garbage
1个回答
2
投票

好吧,这里的问题很微妙(以至于我一开始没有发现问题)。

问题是你在初始化时使用了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赋值。


1
投票

当一个构造函数体得到控制时,类的所有非静态成员都已经被构造出来了。

所以这个数据成员

LinkedList* l = new LinkedList[n];

已经使用数据成员n的不确定值构造了。

重写构造函数的方式如下

hashing(int num) : n( num )
{
}

注意,将类hashing声明为LinkedList的派生类是没有意义的,因为同时你也在使用组成的


1
投票

您的 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.