【问题标题】:Copy consutrctor w/ multiple pointers带有/多个指针的复制构造函数
【发布时间】:2014-10-03 21:40:14
【问题描述】:

我正在尝试为具有指针变量的类创建一个复制构造函数。但是,复制构造出了点问题,因为当我尝试访问新对象中的指针时出现段错误...

/* Copy Constructor */ 
Solver::Solver(const

 Solver &obj)
    {
    // Pointers to use in modified-Midpoint method.
    double *m_yTemp1 = new double[CONST_numVariables];
    double *m_yTemp2 = new double[CONST_numVariables];
    double *m_dTemp  = new double[CONST_numVariables];

    // Triple pointer to store tableau of data for extrapolation.
    double ***m_extrapTableau = new double**[CONST_maxDiv];
    *m_extrapTableau          = *obj.m_extrapTableau;
    for(int i=0; i<CONST_maxDiv; i++)
    {
        m_extrapTableau[i]  = new double*[i+1];
        *m_extrapTableau[i] = *obj.m_extrapTableau[i];
        for(int j=0; j<=i; j++)
        {
            m_extrapTableau[i][j]  = new double[CONST_numVariables];
            *m_extrapTableau[i][j] = *obj.m_extrapTableau[i][j];
        }
    }
    // Pointer of step sizes for extrapolation of modified-Midpoint.
    double *CONST_extrap = new double[CONST_maxDiv];
    for(int i=0; i<CONST_maxDiv; i++)
    {
        CONST_extrap[i] = 2.*(i+1.);
    }

    // Change pointer of new object from already used memory to newly allocated. 
    *m_yTemp1     = *obj.m_yTemp1;
    *m_yTemp2     = *obj.m_yTemp2;
    *m_dTemp      = *obj.m_dTemp;
    *CONST_extrap = *obj.CONST_extrap;
}

我最初的问题是:

  1. 如果类中有其他非指针变量,它们是自动复制的还是我也需要指定它们?
  2. 如何处理传递双指针或三指针的地址?我想我可能做错了。
  3. 如果 CONST_numVariables 和 CONST_maxDiv 是类中设置的常量,是否可以在此复制构造函数中使用它们,假设它们在我复制对象时已设置?

【问题讨论】:

  • 使用std::vector,忘记所有这些三星级的废话。此外,我不确定你想用*m_extrapTableau = *obj.m_extrapTableau; 之类的东西做什么,但它所做的几乎肯定不是你想要的。
  • "如果我在类中有其他非指针变量,它们是自动复制的还是我也需要指定它们?"如果您提供自己的复制构造函数,则不会自动复制任何内容。
  • 仅供参考,您的 intent*m_yTemp1 = *obj.m_yTemp1; 完全不明显,只是复制数组的 first 元素,但是正是正在发生的事情。我也不清楚为什么每一个都是 local 自动变量。 IE。您将 all 声明为您的 copy-ctor 本地,从而隐藏您的实际成员变量,以便它们(真正的成员)完全不变并且在完成时不确定(因此你的段错误)。随之而来的内存泄漏是一个好处。
  • 为避免异常不安全和其他错误,任何类都不应拥有一个以上的原始指针。换句话说,唯一应该拥有指针的类是容器和智能指针的实现。这样做的结果是任何更高级别的类通常根本不需要 copy-ctor,因为它们所有元素的 copy-ctor 都是 DTRT。
  • 如果您想知道人们在谈论什么,see it live here

标签: c++ copy-constructor


【解决方案1】:

你的段错误的问题在这里:

double ***m_extrapTableau = new double**[CONST_maxDiv];  // (1)
*m_extrapTableau          = *obj.m_extrapTableau;        // (2) 

在 (1) 中,您向构造函数声明了一个变量 m_extrapTableau LOCAL。
但是在 (2) 中,我可以看到您有一个同名的班级成员。因此,您的构造函数的本地 m_extrapTableau 将被正确初始化。但它隐藏了将保持未初始化以供后续使用的类成员。

关于你剩下的问题:

1) 如果您实现了复制构造函数,则必须注意复制您需要的所有内容。

2) 传递双重或三重指针的地址要求您在使用表的任何元素之前正确地遍历每个级别以正确初始化指针。您应该考虑使用向量的向量或向量的向量。这些更容易初始化、复制等......

3) 如果它们是 const 并且您没有使用大括号初始化器将它们初始化为另一个值,它们应该可以这样使用。

【讨论】:

  • 只要我们修复一个使用原始指针完成的脆弱实现,不妨指出表初始化内循环中的i&lt;=j 条件是错误的,并且会调用未定义的行为在随后的取消引用中使用时位于顶端。此外,*ptr = *obj.ptr 样式分配的 all (例如此答案中的那个)虽然在语法上没有错误,但仅复制了序列的 first 元素。 std::copystd::memcpy 可能是有保证的。
  • @WhozCraig 我选择了交换到向量,它成功运行所需的时间比在此处发布寻求帮助所需的时间更少。显然,原始指针和它们的多个级别的复制构造函数超出了我的编码经验。当你对i
  • @BenSouthworth 实际上是j&lt;=i,你是对的。我完全是在回答我脑海中的另一个问题。不用担心应该没问题(索引部分,矢量复制部分)。
猜你喜欢
  • 1970-01-01
  • 2016-04-08
  • 2010-10-21
  • 2016-04-13
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多