Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » От куда взялся деструктор?

Ответить
Настройки темы
От куда взялся деструктор?

Пользователь


Сообщения: 136
Благодарности: 0

Профиль | Отправить PM | Цитировать


Решение этой проблемы меня уже порядком достало, поэтому решил спросить у профессионалов, знающих ООП.

Проблема собтвенно в том, что в следующем перезагруженном операторе выполняется 1 коструктор и 2 деконструктора. От куда берется второй деконструктор в этом коде:

vector vector::operator + (const vector &obj)
{
if (this->n != obj.n) cout << "Error: diff. dim\n";
vector tmp(obj.n);
for (long i=0; i<obj.n; i++) {
tmp.x[i] = this->x[i] + obj.x[i];
}
return tmp;
}

У меня здесь динамическое выделение памяти под объекты, и, естественно, что двухразовое выполнение delete ни к чему хорошему привести не может. Поэтому хочу устраниться данную ошибку. Ниже полный код проги:

#define real double
#include <conio.h>
#include <stdio.h>
#include <iostream.h>

//--------------
class vector
{
public:
real *x;
long n;
public:
vector();
vector(long);
~vector();
vector& operator = (const vector&);
vector operator + (const vector&);
};

vector::vector ()
{
n = 1;
x = new real[n];
cout << "constructor \n";
}

vector::vector (long dim)
{
n = dim;
if (n>0) x = new real[n];
cout << "constructor \n";
}

vector::~vector()
{
delete[] x;
n = 0;
cout << "destructor \n";
}

vector& vector::operator = (const vector &obj)
{
if (this->n != obj.n) cout << "Error: diff. dim\n";
for (long i=0; i<obj.n; i++) {
this->x[i] = obj.x[i];
cout << obj.x[i] << " , " << this->x[i] << "\n";
}
return (*this);
}

vector vector::operator + (const vector &obj)
{
if (this->n != obj.n) cout << "Error: diff. dim\n";
vector tmp(obj.n);
for (long i=0; i<obj.n; i++) {
tmp.x[i] = this->x[i] + obj.x[i];
}
return tmp;
}

//-----------
void main()
{
{
vector a(3);
vector b(3);
a + b;
}
getch();
}

//================

результат её выполнения:

constructor
constructor

constructor
destructor
destructor // !!!!!!

destructor
destructor

Отправлено: 03:04, 09-02-2007

 

редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


zl3p
Предлагаю вам ознакомиться с таким понятием, как "конструктор копирования по умолчанию".

Код: Выделить весь код
vector vector::operator + (const vector &obj)
{
  if (this->n != obj.n) cout << "Error: diff. dim\n";
  vector tmp(obj.n);
  for (long i=0; i<obj.n; i++) {
     tmp.x[i] = this->x[i] + obj.x[i];
  }
  return tmp; // (1)
}
void main()
{
{
vector a(3);
vector b(3);
a + b; // (2)
}
getch();
}
В строчке (1) происходят следующие действия: создаётся копия объекта tmp на стеке (используя конструктор копирования, который вы не объявили, но компилятор создал его самостоятельно), объект tmp был уничтожен (с вызовом деструктора, в первый раз). Затем в строке (2) временный объект используется (в данном случае никак не используется) и удаляется (второй вызов деструктора).

В общем решение простое - объявите конструктор копирования, например так
Код: Выделить весь код
vector::vector (const vector &v)
{
   n = v.n;
  x = new real[n];
  *this = v;
  cout << "constructor \n";
}
Кстати, по стандарту создание временного объекта можно опускать. Поэтому один компилятор (gcc4) даже по вашему первоначальному коду генерирует корректную программу (т.к. не создаёт временный объект и тем самым опускает одну пару конструктор/деструктор), а другой (VS2005 в отладочной конфигурации) - нет.

-------
http://ivank.ru


Отправлено: 04:32, 09-02-2007 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Пользователь


Сообщения: 136
Благодарности: 0

Профиль | Отправить PM | Цитировать


Да! Большое спасибо. Наконец-то я понял для чего нужны эти конструкторы копирования.

Отправлено: 17:41, 09-02-2007 | #3


Пользователь


Сообщения: 136
Благодарности: 0

Профиль | Отправить PM | Цитировать


Правда, всё оказалось не так просто....
С ростом размера проги, начали возникать разные глюки. Теперь уже даже не знаю, где искать ошибки.
В частности, ещё не до конца понял как работает простая строка
Цитата:
*this = v;
в конструкторе копирования. Здесь вызывается перезагруженный оператор "=" или происходит побитное копирование?

Кстати, чего лучше такого почитать по ООП, где всё это, и не только, было бы доступно объяснено?

Отправлено: 22:12, 10-02-2007 | #4


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


Цитата:
в конструкторе копирования. Здесь вызывается перезагруженный оператор "=" или происходит побитное копирование?
Перегруженный оператор. Мне лень было писать цикл для копирования второй раз.

Цитата:
Кстати, чего лучше такого почитать по ООП, где всё это, и не только, было бы доступно объяснено?
Эти вопросы к ООП отношения не имеют по большому счёту. Они имеют отношение к реализации принципов этого подхода в конкрутном языке (C++). Соответственно любая приличная книга по плюсам даст на них ответы. Шестой год всем рекомендую Страуструпа. На самом деле, очень доходчиво и просто (может, и не совсем на новичков, но специальных знаний и опыта не трубет).

-------
http://ivank.ru


Отправлено: 22:52, 10-02-2007 | #5



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » От куда взялся деструктор?

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Ошибка - Куда изчезли файлы? Anva Microsoft Windows 2000/XP 1 28-01-2009 18:08
[решено] Куда пойти? Карина Вебмастеру 6 24-10-2008 19:48
куда поместить файл irik Вебмастеру 3 02-12-2003 19:10
куда писАть Belomor О сайте и форуме 1 02-04-2002 09:06
Куда Вы Пропадали ? ruslandh О сайте и форуме 8 24-03-2002 19:18




 
Переход