Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Объясните конструкцию ptr->~ClassName() 
V
    Опции темы
borisbn
Дата 24.3.2011, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



В различном коде не часто, но встречается конструкция вида
Код

ClassName * ptr;
...
if ( ptr ) {
    ptr->~ClassName();
}

Можете объяснить назначение такого вызова ?
Правильно ли я понимаю, что delete делает примерно следующее:
Код

ClassName::delete() {
    this->~ClassName();
    free( this );
}

а ptr->~ClassName(); только вызывает деструктор, а память не освобождает ?
Если правильно, то подскажите, пожалуйста, в каких случаях это используется.
Спасибо.

Это сообщение отредактировал(а) borisbn - 24.3.2011, 10:58


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 24.3.2011, 11:04 (ссылка)   | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



borisbn

В C++ есть возможность создать объект в заранее выделенной области памяти.
Код

struct A {};

int main ()
{
    A* ptr = static_cast<A*>(operator new(sizeof(A)));
    new (ptr) A;
}

По сути это явный вызов конструктора. Аналогично для удаление этого объекта необходимо вызвать деструктор и освободить память.
Код

ptr->~A();
operator delete (ptr);

PM   Вверх
Modul
Дата 24.3.2011, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Код

delete pPointer;


При этом происходит не удаление указателя, а освобождение области памяти по адресу, записанному в нем. С самим указателем ничего не происходит и ему можно присвоить другой адрес. Рекомендуется указателю присваивать нулевое значение.


Цитата(borisbn @  24.3.2011,  10:57 Найти цитируемый пост)
только вызывает деструктор, а память не освобождает ?


Да. Поэтому оператор delete предпочтительнее (освобождает память и удаляет объект).

Цитата(borisbn @  24.3.2011,  10:57 Найти цитируемый пост)
подскажите, пожалуйста, в каких случаях это используется.

А что у нас обычно в деструкторе ? Что-то удаляем (объекты).

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

Т.е. для освобождения памяти и удаления объектов класса.

В конструкторе:
Код

int * pPointer = new int;


В деструкторе:
Код

delete pPointer;


А наш объект (типа ClassName) при этом не удаляем, только чистим память.

Это сообщение отредактировал(а) Modul - 24.3.2011, 11:56
--------------------
I'll be back !
PM MAIL   Вверх
borisbn
Дата 24.3.2011, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(azesmcar @  24.3.2011,  11:04 Найти цитируемый пост)
В C++ есть возможность создать объект в заранее выделенной области памяти.

возможность то есть... а можете привети примеры, в которых это необходимо (требуется) применять ?
Другими словами, что это за случаи, когда нельзя сделать "по-человечески" new/delete ?


Цитата(Modul @  24.3.2011,  11:37 Найти цитируемый пост)
С самим указателем ничего не происходит

Цитата(Modul @  24.3.2011,  11:37 Найти цитируемый пост)
Рекомендуется указателю присваивать нулевое значение.

Цитата(Modul @  24.3.2011,  11:37 Найти цитируемый пост)
А что у нас обычно в деструкторе ? Что-то удаляем (объекты).

ты считаешь, что я этого не знаю ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 24.3.2011, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(borisbn @  24.3.2011,  11:58 Найти цитируемый пост)
возможность то есть... а можете привети примеры, в которых это необходимо (требуется) применять ?

Например тебе необходимо создать огромное количество мелких объектов, и чтобы не вызывать проблем с фрагментацией памяти выделяешь сразу большой кусок, в котором в дальнейшем создаешь свои объекты. Или например твоей программе требуется много памяти, и чтобы в дальнейшем избежать исключения с bad_alloc ты при запуске выделяешь столько, сколько необходимо (если есть) и работаешь уже с выделенной памятью. Примеров много, другое дело, что это не часто требуется.

Это сообщение отредактировал(а) azesmcar - 24.3.2011, 12:04
PM   Вверх
Modul
Дата 24.3.2011, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(borisbn @  24.3.2011,  11:58 Найти цитируемый пост)
ты считаешь, что я этого не знаю ?


Конечно знаешь ! Просто сразу не догадался, потому спросил.  smile 


Цитата(azesmcar @  24.3.2011,  12:01 Найти цитируемый пост)
выделяешь сразу большой кусок, в котором в дальнейшем создаешь свои объекты.


А потом еще надо отдельную функцию сделать, чтобы их снова в динамике создать.
Подумалось.

Итого у нас для раздумий 2 варианта.
--------------------
I'll be back !
PM MAIL   Вверх
borisbn
Дата 24.3.2011, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



azesmcar, т.е. (если я правильно понял) это используется только когда сам делашь менеджер памяти (ну или, скажем, его основной функционал).
OK, спасибо. закрываю.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 24.3.2011, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(borisbn @  24.3.2011,  12:12 Найти цитируемый пост)
azesmcar, т.е. (если я правильно понял) это используется только когда сам делашь менеджер памяти (ну или, скажем, его основной функционал).

Не только, скорее в основном. Явный вызов деструктора нужен тогда, когда ему предшествовал явный вызов конструктора. Еще один пример использования можешь посмотреть у Александреску - phoenix singleton.

В общем-то это возможность языке, а где и как ее применять личное дело каждого.

Цитата(Modul @  24.3.2011,  12:10 Найти цитируемый пост)
А потом еще надо отдельную функцию сделать, чтобы их снова в динамике создать.

не совсем понял о чем речь.

Это сообщение отредактировал(а) azesmcar - 24.3.2011, 12:17
PM   Вверх
Modul
Дата 24.3.2011, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(azesmcar @  24.3.2011,  12:14 Найти цитируемый пост)
не совсем понял о чем речь.


Если мы дальше хотим работать с объектом, 
снова надо эти мелкие объекты (может массивы) создать после их удаления в деструкторе
в отдельной функции.

--------------------
I'll be back !
PM MAIL   Вверх
bsa
Дата 24.3.2011, 12:29 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Modul @  24.3.2011,  12:19 Найти цитируемый пост)
Если мы дальше хотим работать с объектом, 
снова надо эти мелкие объекты (может массивы) создать после их удаления в деструкторе
в отдельной функции.
Че?

Посмотрите реализацию std::vector. Там это используется - reserve() выделяет блок памяти, resize() создает объекты в уже выделенной области.
PM   Вверх
Modul
Дата 24.3.2011, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



bsa, я про такой вариант:

Код

int * pPointer = new int;


Думаю, может меня остальные не поняли.

При создании объекта имеется динамическое распределение памяти (мелкие объекты), выделение памяти сделали в конструкторе, ее освобождение - в деструкторе.

Вызвали явно деструктор, мелкие объекты удалили. 

При дальнейшей работе с нашим объектом (его не удалили) эти мелкие динамические объекты снова создаем через отдельный метод.

Это сообщение отредактировал(а) Modul - 24.3.2011, 12:46
--------------------
I'll be back !
PM MAIL   Вверх
bsa
Дата 24.3.2011, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Modul, я опять не понял, о чем ты говоришь. Если об освобождении ресурсов деструктором, которые выделил конструктор, то это и ежу понятно. Причем не важно, выделялись ли они на самом деле или нет. Если сконструировал объект, то изволь его затем деконструировать. И не важно, int это, или мега сложный класс управления стержнями ядерного реактора.
PM   Вверх
borisbn
Дата 24.3.2011, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



bsa, хммм. Действительно, каждый день пользую, а не подумал про вектор. Там, пожалуй, по-другому и не сделаешь.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Modul
Дата 24.3.2011, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(Modul @  24.3.2011,  12:10 Найти цитируемый пост)
Итого у нас для раздумий 2 варианта.


1) delete myObject;

Цитата(bsa @  24.3.2011,  13:49 Найти цитируемый пост)
Если сконструировал объект, то изволь его затем деконструировать. 


С этим всем ясно ! smile 

2) По сабжу собственно:

1. создали объект

ClassName *myObject = new ClassName;

В конструкторе у нас были мелкие динамические объекты, типа:
Код

int * pPointer = new int;



2. вызвали явно деструктор
myObject->~ClassName();

и удалили все наши мелкие динамические объекты. 
delete pPointer;

Объект myObject у нас существует - занимает память, а наши мелкие динамические объекты удалены.

3. Для новой работы с объектом myObject требуется создать снова наши мелкие динамические объекты,
созданные в конструкторе (например, pPointer).
Для этого я предлагал сделать отдельную функцию.

И шото меня не поняла общественнось. smile 
--------------------
I'll be back !
PM MAIL   Вверх
bsa
Дата 24.3.2011, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Modul @  24.3.2011,  14:24 Найти цитируемый пост)
И шото меня не поняла общественнось. 

Да потому что ты какую-то ерунду сморозил. Назови хоть один пример, когда требуется делать так, как ты рекомендуешь?

Непосредственный вызов деструктора используется ТОГДА И ТОЛЬКО ТОГДА, когда использовался размещающий new. Так как этот оператор просто вызывает конструктор, передавая ему в качестве указателя this адрес заданной тобой области памяти. Используется это для создания так называемых пулов - собственных "куч".
Пример:
Код
class X;
char *pool = new char[sizeof(X) * 1000];
...
X *p = new (pool + sizeof(X) * 100)(12); //создать объект класса X по адресу pool + sizeof(X) * 100, и передать его конструктору 12
...
p->~X(); //уничтожить объект
...
delete []pool;


Это сообщение отредактировал(а) bsa - 24.3.2011, 16:03
PM   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0639 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.