Russian Qt Forum
Ноябрь 27, 2024, 08:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Преждевременный вызов деструктора  (Прочитано 17404 раз)
Даниил
Гость
« : Март 13, 2012, 14:06 »

Приветствую всех.
Появилась внезапная трабла - хочу запихать в вектор свой класс. Только вот незадача, как только я push_back'аю объект в вектор, тот вызывает деструктор, при чем имеется какая-то странная зависимость от количества "запинаных" объектов, посмотрите, подскажите - где тут засада.
Код
C++ (Qt)
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
 
class Coord
{
private:
   int x, y;
public:
   Coord(){x = 0; y = 0;}
   Coord(int _x, int _y){x = _x; y = _y;}
   Coord(const Coord &c){x = c.x;}
   ~Coord(){cout << "Delete Coord[" << x << ',' << y << "]" << endl;}
   Coord &operator=(const Coord &c);
   bool operator <(const Coord &c) const;
   friend ostream &operator <<(ostream& s, const Coord &c);
};
 
Coord &Coord::operator =(const Coord &c)
{
   if(this == &c)return *this;
   else
   {
       this->x = c.x;
       this->y = c.y;
       return *this;
   }
}
 
bool Coord::operator <(const Coord &c)const
{
   if(this->x < c.x)return true;
   else if(this->x == c.x)
   {
       if(this->y < c.y)return true;
   }
   return false;
}
 
ostream &operator <<(ostream& s, const Coord &c)
{
   cout << "Coord[" << c.x << "," << c.y << "]" << endl;
   return s;
}
 
int main()
{
   vector<Coord> v;
   v.push_back(Coord());
   v.push_back(Coord());
   v.push_back(Coord());
   cout << v[0];
   cout << v[1];
   cout << v[2];
 
   getchar();
   return 0;
}
 
Вывод:
Код:
Delete Coord[0,0]
Delete Coord[0,11665604]
Delete Coord[0,0]
Delete Coord[0,11665604]
Delete Coord[0,825111086]
Delete Coord[0,0]
Coord[0,11669608]
Coord[0,2037603443]
Coord[0,1127952947]
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Март 13, 2012, 14:09 »

Все правильно - вектор хранит копию объекта. При изменении вектора происходит перераспределение объектов копированием.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Даниил
Гость
« Ответ #2 : Март 13, 2012, 14:25 »

м-м-м, поставлю вопрос конкретней - что нужно сделать, чтобы можно было в векторе хранить самописные объекты.
Записан
mutineer
Гость
« Ответ #3 : Март 13, 2012, 14:27 »

м-м-м, поставлю вопрос конкретней - что нужно сделать, чтобы можно было в векторе хранить самописные объекты.

Они уже сейчас там хранятся. В чем проблема-то?
Записан
Даниил
Гость
« Ответ #4 : Март 13, 2012, 14:29 »

Ну, вобще проблема есть - т.к. там хранится не то, что туда запихивали:
Код:
Coord[0,11669608]
Coord[0,2037603443]
Coord[0,1127952947]
Записан
ddrtn
Гость
« Ответ #5 : Март 13, 2012, 14:31 »

Это потому, что у Вас неправильно определен конструктор копирования.  в нем копируется только х
Записан
mutineer
Гость
« Ответ #6 : Март 13, 2012, 14:32 »

Ну, вобще проблема есть - т.к. там хранится не то, что туда запихивали:
Код:
Coord[0,11669608]
Coord[0,2037603443]
Coord[0,1127952947]

Вектор копирует объекты. Причем не один раз (при перераспределении памяти)
А у тебя неполный конструктор копирования
Код
C++ (Qt)
Coord(const Coord &c){x = c.x;}
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #7 : Март 13, 2012, 14:32 »

Coord(const Coord &c){x = c.x;} - а y игноришь, вот и получаешь мусор.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Даниил
Гость
« Ответ #8 : Март 13, 2012, 14:35 »

Спасибо. Прозрел. Показает язык
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #9 : Март 13, 2012, 14:38 »

В данном случае свой копирующий конструктор и опрератор присваивания не нужны, так как класс тривиален.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Даниил
Гость
« Ответ #10 : Март 13, 2012, 17:43 »

Да я класс обрезал, чтобы сюда не кидать 300 строк кода, а так да, только в теории нужно еще оператор == перегрузить, а то вектор может начать ругаться.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Март 13, 2012, 17:55 »

Конструктор лучше оформить так
Код
C++ (Qt)
Coord( int _x = 0, int _y = 0 )  { x = _x; y = _y; }
 
Тогда он годится и по умолчанию

А оператор < написать проще, (а то у Вас голову можно сломать)

Код
C++ (Qt)
bool Coord::operator < ( const Coord & c ) const
{
   if (x < c.x) return true;
   if (x > c.x) return false;
   return y < c.y;
}
 
Оператор == вектору не требуется, но в такого класса нужен все равно
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #12 : Март 13, 2012, 18:40 »

Конструктор лучше оформить так
Код
C++ (Qt)
Coord( int _x = 0, int _y = 0 )  { x = _x; y = _y; }
 
Тогда он годится и по умолчанию

А оператор < написать проще, (а то у Вас голову можно сломать)

Код
C++ (Qt)
bool Coord::operator < ( const Coord & c ) const
{
   if (x < c.x) return true;
   if (x > c.x) return false;
   return y < c.y;
}
 
Оператор == вектору не требуется, но в такого класса нужен все равно


А оператор < вообще бредово определять для данного класса)
Какая точка будет больше p1(10, 1) или p2(1, 10) ?

Согласно вашей реализации p1 окажется больше.. Но с чего это вы нарушаете равноправие между x и y компонентами?
И как конечный пользователь должен досмысливать поведение такого оператора для объекта точки? Это не логично.
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #13 : Март 13, 2012, 18:44 »

Да и ещё:
Обычно так не пишут:
Код
C++ (Qt)
Coord &Coord::operator =(const Coord &c)
{
   if(this == &c)return *this;
   else
   {
       this->x = c.x;
       this->y = c.y;
       return *this;
   }
}
 

Лучше так:
Код
C++ (Qt)
Coord &Coord::operator =(const Coord &c)
{
   if (this != &c)
   {
       x = c.x;
       y = c.y;
   }
   return *this;
}
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Март 13, 2012, 18:58 »

А оператор < вообще бредово определять для данного класса)
Какая точка будет больше p1(10, 1) или p2(1, 10) ?

Согласно вашей реализации p1 окажется больше.. Но с чего это вы нарушаете равноправие между x и y компонентами?
И как конечный пользователь должен досмысливать поведение такого оператора для объекта точки? Это не логично.
Не всегда концептуальность идет в такт с конкретикой/реализацией. Есть вектор точек, надо удалить повторяющиеся. Что будете делать без оператора < ? Или у Вас есть др. предложения как его определить? Так что потише там с "бредово" и.т.п.  Улыбающийся

Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.3 секунд. Запросов: 23.