【问题标题】:Passing variable to constructor to a derived class gives garbage value, both the base and derived class's constructors have different parameters. Why?将变量传递给派生类的构造函数会产生垃圾值,基类和派生类的构造函数都有不同的参数。为什么?
【发布时间】:2020-04-30 20:50:24
【问题描述】:

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

将变量传递给派生类的构造函数时,在声明基类数组时会给出垃圾值。数组大小不是 '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'传递给该函数。它仍然给出一个错误。我认为 LinkedList 类数组的初始化存在一些问题,但我不知道是什么?

标签: c++ oop constructor garbage


【解决方案1】:

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

问题是您在类成员初始化期间使用 n (this-&gt;n) 的值进行初始化。

问题是,在 C++ 中,这些初始化程序都是在成员初始化期间运行的,这在构造函数体之前。由于直到构造函数主体才设置 this-&gt;n 的值,所以 this-&gt;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

最后,我会确保您正确处理破坏和复制/移动分配。

【讨论】:

    【解决方案2】:

    当构造函数的主体得到控制时,该类的所有非静态成员都已经构造完毕。

    所以这个数据成员

    LinkedList* l = new LinkedList[n];
    

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

    按如下方式重写构造函数

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

    请注意,将散列类声明为 LinkedList 的派生类是没有意义的,因为同时您也在使用组合

    【讨论】:

      【解决方案3】:

      您的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;
      }
      

      【讨论】:

      • 在构造函数的外部或内部分配 LinkedList* 有什么区别?我没有很好地理解它。谢谢它确实解决了我的问题。
      • 构造函数是对象的入口点。如果你不在构造函数中初始化东西,它们根本不会被初始化。
      猜你喜欢
      • 1970-01-01
      • 2016-07-19
      • 2016-12-20
      • 2018-07-16
      • 2021-02-14
      • 2018-07-21
      • 2014-06-23
      • 1970-01-01
      • 2011-02-24
      相关资源
      最近更新 更多