При вызове "aaa.NewX(77)" (см. ниже) для temp деструктор почему-то вызывается дважды в результате программа выдаёт ошибку когда пытается второй раз удалить *X.
Может кто подскажет как написать это правильно. (компилировалось на MS VC++ v7)
class A
{
public:
A() { X = new int; }
~A(){ delete X; }
A NewA(int a);
int *X;
};
A A::NewA(int a)
{
A temp;
*(temp.X) = a;
return temp;
}
Чтобы решить проблему, тебе нужен свой собственный конструктор копирования и оператор присваивания, потому что компилятору невдомек, что ты вкладываешь другой смысл в копирование указателей:
class A
{
public:
...
A(const A &a) : X(a.X ? new int(*(a.X)) : 0)
{
}
A& operator = (const A &a)
{
A(a).swap(*this);
return *this;
}
void swap(A &a)
{
std::swap(X, a.X);
}
...
};
N>class A
N>{
N>public:
N> A() { X = new int; }
N> ~A(){ delete X; }
N> A NewA(int a);
N> int *X;
N>};
N>A A::NewA(int a)
N>{
N> A temp;
N> *(temp.X) = a;
N> return temp; /*Вот здесь выполняется почленное копирование, после чего
вызывается деструктор для temp. *X удаляется */
N>}
N>main()
N>{
N>A aaa;
N>aaa.NewA(77); /*А здесь деструктор вызывается для удаления временного объекта,
при этом *X указывает на удаленный объект*/
N>}
Вообще если в классе есть указатели, надо переопределять оператор присваивания и копирующий конструктор.
Здравствуйте, -newbie-, Вы писали:
N>При вызове "aaa.NewX(77)" (см. ниже) для temp деструктор почему-то вызывается дважды в результате программа выдаёт ошибку когда пытается второй раз удалить *X. N>Может кто подскажет как написать это правильно. (компилировалось на MS VC++ v7)
N>class A N>{ N>public: N> A() { X = new int; } N> ~A(){ delete X; } N> A NewA(int a); N> int *X; N>};
N>A A::NewA(int a) N>{ N> A temp; N> *(temp.X) = a; N> return temp; N>}
N>main() N>{ N>A aaa; N>aaa.NewA(77); N>}
Попробуй в деструкторе
~A(){if(X) {delete X; X = NULL;} }
Здравствуйте, DanilB, Вы писали:
DB>Попробуй в деструкторе DB>~A(){if(X) {delete X; X = NULL;} }
Ну это не поможет.
Как я понял из выше сказанного, в "return temp" передаётся не сам temp а его копия.
И т.к. компилятор "не знает" как копировать память на которую ссылается *X, то нужно определить контсруктор копирования A(const A &a), где а — объект который копируется.
Так что, деструктор вызывается по одному разу для двух разных объектов. Один раз для temp в строке "return temp". И второй раз для его копии в aaa.NewA(77);