复制构造函数中的递归调用

recursive call in copy constructor

提问人:Daniyal Yasin 提问时间:10/10/2018 最后编辑:NathanOliverDaniyal Yasin 更新时间:10/10/2018 访问量:1242

问:

我按照三法则实现了一个类,但我崩溃了。在调试时,我得出的结论是复制构造函数正在重复调用自身,而不是调用相等运算符。为什么会这样?它不应该调用相等运算符吗?

#include <iostream>
#include <deque>
#include <cstdlib>
#define LENGTH 128

typedef struct tDataStruct
{

char strA[LENGTH];

char strB[LENGTH];
int nNumberOfSignals;
double* oQueue;

tDataStruct()
{
    nNumberOfSignals = 0;
    //oQueue = NULL;
    memset(strA, 0, LENGTH);
    memset(strB, 0, LENGTH);
}

~tDataStruct()
{
    if (NULL != oQueue)
    {
        delete[] oQueue;
        oQueue = NULL;
    }
}

tDataStruct(const tDataStruct& other) // copy constructor
{
    if (this != &other)
    {
        *this = other;
    }

}
tDataStruct& operator=(tDataStruct other) // copy assignment
{
    if (this == &other)
    {
        return *this;
    }
    strncpy_s(strA, other.strA, LENGTH);
    strncpy_s(strB, other.strB, LENGTH);
    nNumberOfSignals = other.nNumberOfSignals;
    if (NULL != oQueue)
    {
        delete[] oQueue;
        oQueue = NULL;
    }
    if (other.nNumberOfSignals > 0)
    {
        //memcpy(oQueue, other.oQueue, nNumberOfSignals);
    }
    return *this;
}
} tDataStruct;


int main()
{
    tDataStruct tData;

    std::deque<tDataStruct> fifo;

    fifo.push_back(tData);
}
C++ 构造函数复制 赋值 法则

评论

0赞 François Andrieux 10/10/2018
如果使用而不是所有编译器生成的成员,则生成的成员将正确运行。std::array<char, LENGTH>char [LENGTH]std::vector<double>double*
0赞 Martin York 10/10/2018
这不是标准的方法。通常,赋值运算符在称为“复制和交换”(查找)的惯用语中使用复制构造函数。因此,这样做会导致 UB ( 可能在未初始化的变量上调用。因此,您正在随机删除内存的某些部分(这不是一个好主意)。delete[] oQueue
0赞 Daniyal Yasin 10/10/2018
是的,我已经发现了那个错误。谢谢

答:

7赞 NathanOliver 10/10/2018 #1

在复制构造函数中,使用

*this = other; //(1)

其中调用

tDataStruct& operator=(tDataStruct other)  //(2)

由于是按值传递的,它需要制作副本。然后调用 ,哪个调用,然后调用哪个然后调用,一轮又一轮,你将一直走到程序崩溃/终止。other1212

你需要通过参考来获取,这样你就不会真正制作一个副本other

tDataStruct& operator=(const tDataStruct& other) 

所有这一切都说你是在倒退。您应该使用 copy 和 swap 惯用语,并使用 copy 构造函数实现您的。operator =

0赞 Michael Veksler 10/10/2018 #2

复制构造函数调用 assignment:

tDataStruct(const tDataStruct& other) // copy constructor
{
    // NOTE: this redundant check is always true. 
    // Please remove the if.
    if (this != &other) 
    {
        *this = other;
    }
 }

然后,由于赋值运算符按值(而不是按引用)获取对象,因此调用复制构造函数以复制参数:

tDataStruct& operator=(tDataStruct other) // copy assignment
{

这就是你得到相互递归的方式。

请尝试改为按引用传递:

tDataStruct& operator=(const tDataStruct &other) // copy assignment