Рекурсивный вызов в конструкторе копирования
Я реализовал класс, следуя правилу трех, и получаю сбой. После отладки я пришел к выводу, что конструктор копирования вызывает сам себя несколько раз вместо вызова оператора равенства. Почему это так? Разве это не должно вызывать оператор равенства?
#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);
}
2 ответа
В вашем конструкторе копирования вы используете
*this = other; //(1)
какие звонки
tDataStruct& operator=(tDataStruct other) //(2)
как other
передается по значению, он должен сделать копию. Что тогда звонит 1
, который называют 2
который затем вызывает 1
который затем вызывает 2
и раунд и раунд вы будете идти, пока программа не завершится сбоем / завершается.
Вам нужно взять other
по ссылке, так что вы на самом деле не делаете копию, как
tDataStruct& operator=(const tDataStruct& other)
Все это говорит о том, что вы делаете это задом наперед. Вы должны использовать идиому копирования и обмена и реализовать свой operator =
используя ваш конструктор копирования.
Ваш конструктор копирования вызывает присваивание:
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