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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: При добавлении в QList вызывается деструтор. Зачем?  (Прочитано 4159 раз)
Yan
Гость
« : Январь 28, 2007, 21:34 »

Создаю QList:
mainwindow.h:
Код:

..
public:
QList<CScreenShot> screenShots;
...


Класс CScreenShot кроме конструктора и деструктора ничего не содержит:
screenshot.h:
Код:

...
class CScreenShot{
public:
CScreenShot();
~CScreenShot();
};
...

screenshot.cpp:
Код:

CScreenShot::CScreenShot()
{
QMessageBox::about(NULL, "About","constructor");
}
CScreenShot::~CScreenShot(){
QMessageBox::about(NULL, "About","destructor");
}


Добаляю новый элемент в QList так:
mainwindow.cpp:
Код:

...
screenShots.append(CScreenShot());
...


При добавлении зачем-то помимо конструктора CScreenShot(), вызывается ещё и деструктор ~CScreenShot().
Зачем?
Где я ошибся?

добавлено спустя 4 минуты:

  P.S. QT 4.1.0 под Windows
Записан
alex12
Гость
« Ответ #1 : Январь 28, 2007, 22:36 »

Код:

...
screenShots.append(CScreenShot());
...


Здесь сначала создается анонимный экземпляр класса, а потом при помощи конструктора копий создается новый экземпляр. Именно этот новый экземпляр помещается в контейнер. После этого анонимный объект уничтожается деструктором (что мы и видим). Создание второго экземпляра не отслеживается т.к. он делается конструктором копий, а не конструктором по умолчанию.

По-моему это работает именно так.
Записан
Yan
Гость
« Ответ #2 : Январь 28, 2007, 23:22 »

Хорошо, тогда как мне отследить этот момент, и сделать так, чтобы код в деструкторе выполнялся только при удалении элемента из QList, например:
Код:
screenShots.removeFirst();
Записан
alex12
Гость
« Ответ #3 : Январь 28, 2007, 23:54 »

Вот здесь и начинается C++ Веселый

Контейнеры Qt хранят данные по значению, но сами Qt типы с данными при этом используют метод хранения copy-on-write. Поэтому можно спокойно копировать любые QByteArray или QImage без размножения самих данных и потери скорости.

В случае запихивания класса в контейнер без его копирования не обойтись. Отследить же реальное его уничтожение можно, думаю, при помощи подсчета ссылок. Для этого нужно переопределить конструктор копий и при создании копии увеличивать счетчик, а в деструкторе его уменьшать. Это одна из стандартных идиом C++.

Все это относительно сложно и нельзя ли обойтись без этого?
Записан
Yan
Гость
« Ответ #4 : Январь 29, 2007, 03:30 »

Да, пожалуй, обойдусь более простым решением.
Спасибо.
Записан
Dendy
Гость
« Ответ #5 : Январь 29, 2007, 08:38 »

Более простое решение - поместить данньІе класса CScreenShot в обёртку с подсчётом ссьІлок, что будет заниматься их вьІделением и унитожением. Кроме того в Qt предусмотрен механизм атомарного копирования между потоками таких данньІх.

Код:
class CScreenShotData : public QSharedData
{
public:
  CScreenShotData()
  {
    // real constructor
  }

  ~CScreenShotData()
  {
    // real destructor
  }
};


class CScreenShot
{
public:
  CScreenShot();

private:
  QSharedDataPointer<CScreenShotData> d;
};


Теперь деструктор будет вьІзьІваться только при уничтожении последнего обьекта, что ссьІлается на данньІе.
Записан
alex12
Гость
« Ответ #6 : Январь 29, 2007, 11:58 »

Теперь буду знать как не изобретать велосипед. Веселый
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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