LINUX.ORG.RU

как вручную уничтожить статический объект?


0

0

#include<iostream>
class MyString{

public:
int Ind;
void show(){
std::cout<<Ind<<std::endl;
}

explicit MyString(int I){
Ind=I;
std::cout<<«constr»<<Ind<<«adress»<<&Ind<<std::endl;
}
~MyString(){
std::cout<<«destr»<<Ind<<«adress»<<&Ind<<std::endl;
//Ind=0;

}
};

int main(int argc, char *argv[])
{

std::cout<<«begin»<<std::endl;
MyString G(1);
std::cout<<&G<<std::endl;
std::cout<<«G»<<std::endl;
G.~MyString();
G=MyString(2);
std::cout<<&G<<std::endl;
std::cout<<«G»<<std::endl;
G.show();
G.~MyString();
G=MyString(3);
std::cout<<&G<<std::endl;

//std::cout<<«begin»<<std::endl;
/*for(int i=0;i<4;i++){
MyString g(i);
std::cout<<&g<<std::endl;
g.show();

}*/
//MyString *pj;
/*
for(int k=0;k<5;k++){

std::cout<<«for1»<<std::endl;
for(int i=0;i<4;i++){
MyString j(i);
std::cout<<j.Ind<<std::endl;
pj=&j;
j.Ind=i;
std::cout<<pj<<std::endl;
}

std::cout<<«endfor1»<<std::endl;
std::cout<<(*pj).Ind<<std::endl;
(*pj).Ind=k;
}*/
std::cout<<«end»<<std::endl;
}


____________________________________________________________
вывод:
begin
constr1adress0xbfa761e4
0xbfa761e4
G
destr1adress0xbfa761e4
constr2adress0xbfa761e8
destr2adress0xbfa761e8
0xbfa761e4
G
2
destr2adress0xbfa761e4
constr3adress0xbfa761ec
destr3adress0xbfa761ec
0xbfa761e4
end
destr3adress0xbfa761e4
_____________________________________________________________
вопрос:
1. Как мне явно вызвать деструктор для статической переменной
2. Корректен ли вышеприведённый вывод, я вижу здесь изменение адреса(которого быть не должно), destr1adress0xbfa761e4
constr2adress0xbfa761e8
destr2adress0xbfa761e8
0xbfa761e4
это вообще какой-то бред.
В общем этот вывод вообще корректен?

был на этой странице:
http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.5
у меня проблемы с англ, но по-моему здесь ответа на мой вопрос нет, потому что в моём случае я вызываю диструктор явно и у меня начинают лезть какие-то глюки, а там написано что деструктор просто вызовется при }

> G.~MyString();

G=MyString(2);

Жестоко. Для этой цели есть operator= и в данном случае он вызывается у объекта после вызова деструктора. Автоматические (а не статические) объекты руками уничтожать нельзя. .~ и ->~ придуманы для простреливания ног.

const86 ★★★★★
()
Ответ на: комментарий от ferrum2688

Лишний код бы убрал и нормальный, отформатированный вывод сделал, а то читать такое жуть. Не вижу никакого изменения адреса.

begin
constr = 1 adress = 0xbf944f60
0xbf944f60
G
destr = 1 adress = 0xbf944f60
constr = 2 adress = 0xbf944f64
destr = 2 adress = 0xbf944f64
0xbf944f60
G
2
destr = 2 adress = 0xbf944f60
constr = 3 adress = 0xbf944f68
destr = 3 adress = 0xbf944f68
0xbf944f60
end
destr = 3 adress = 0xbf944f60
Booster ★★
()
Ответ на: комментарий от ferrum2688
destr1adress0xbfa761e4
constr2adress0xbfa761e8
destr2adress0xbfa761e8
0xbfa761e4

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

Booster ★★
()
Ответ на: комментарий от ferrum2688

Ну тогда все ок, и вывод программы соответствует коду)

Hint: смотри внимательнее на строку G=MyString(2); Попытайся представить во всех подробностях, какие действия/вызовы ей соответствуют.

AF ★★★
()

ты не должен этого хотеть

jtootf ★★★★★
()

>Как мне явно вызвать деструктор для статической переменной

Зачем?

yoghurt ★★★★★
()

Собственно, а чего ты ожидаешь после гипотетического «удаления» статического объекта?

madcore ★★★★★
()

Деструктор можно вызвать для любого указателя на объект. Но если вызвать его для указателя на статический объект, то это, видимо, undefined behaviour, потому что ты никак не можешь сообщить среде выполнения, что он уничтожен — потом среда выполнения сама вызовет деструктор повторно.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

>Но если вызвать его для указателя на статический объект, то это, видимо, undefined behaviour, потому что ты никак не можешь сообщить среде выполнения, что он уничтожен — потом среда выполнения сама вызовет деструктор повторно.
Не городи огород. Деструктор это обычный метод, от того что он вызовется не один раз, ещё ничего худого не обещает.

Booster ★★
()
Ответ на: комментарий от Booster

Деструктор это обычный метод, от того что он вызовется не один раз, ещё ничего худого не обещает.

тривиальный деструктор незачем вызывать явно; нетривиальный деструктор, как правило, неидемпотентен

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

>тривиальный деструктор незачем вызывать явно; нетривиальный деструктор, как правило, неидемпотентен
Это другой вопрос. Я лишь хотел сказать, что это никак не UB.

Booster ★★
()
Ответ на: комментарий от Booster

>Это никакой не бред. Вызов деструктора, вызов конструктора временного объекта, и убиение временного объекта. это бред, т.к. деструктор вызвался сразу после конструктора, т.е. ниже объект уже не такой какой нужно.

ferrum2688
() автор топика

char m [sizeof T];
T * t1 = new (m) T;
t->~T();
T * t2 = new (m) T;

gavv
()
Ответ на: комментарий от Booster

Оно конечно все так, но иногда таки надо

неудачный пример. delete тоже вызывает ~T(), но так же, как и аллокатор, делает это без непосредственного участия программиста

Это другой вопрос

тот самый

это никак не UB.

повторный вызов нетривиального деструктора - это практически однозначное UB

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

>повторный вызов нетривиального деструктора - это практически однозначное UB
Да ты шо, как раз DB - или сегфолт или всё работает нормально. Практически однозначного UB не бывает.

Booster ★★
()
Ответ на: комментарий от Booster

Да ты шо, как раз DB - или сегфолт или всё работает нормально. Практически однозначного UB не бывает.

ок. практически однозначная жопа. такая формулировка устраивает?

jtootf ★★★★★
()
Ответ на: комментарий от Booster

от того что он вызовется не один раз, ещё ничего худого не обещает

два раза закрыть файловый дескриптор, два раза удалить owned поля, хранящиеся по указателю - для тебя это ничего худого? два раза выполнить любую логику, завязанную на RFID - ничего худого?

это не UB

уговорил, это таки жопа. полная

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

>неудачный пример. delete тоже вызывает ~T(), но так же, как и аллокатор, делает это без непосредственного участия программиста

А аллокаторы боги пишут, да?

AF ★★★
()
Ответ на: комментарий от Booster

> Писал, что повторный вызов деструктора не UB. ^)

вызов деструктора класса заканчивает время жизни объекта. Объекта этого класса на этом месте больше нет, нельзя для него вызвать никакой метод, в том числе и деструктор.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

>вызов деструктора класса заканчивает время жизни объекта. Объекта этого класса на этом месте больше нет, нельзя для него вызвать никакой метод, в том числе и деструктор

На С++ можно.

AF ★★★
()
Ответ на: комментарий от AF

ты не должен этого хотеть

и как наличие явного вызова деструктора в operator delete() и аллокаторах противоречит этому утверждению? и какое вообще отношение аллокаторы имеют к статическим объектам?

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

Мы знаем, что эта задача НЕ имеет решения, но нам интересно посмотреть , КАК она решается ))

... а тут ты со своими рекомендациями - чего хотеть, а чего нет.

AF ★★★
()
Ответ на: комментарий от AF

а тут ты со своими рекомендациями - чего хотеть, а чего нет

ну кто-то должен же был это сказать. во имя луны

jtootf ★★★★★
()
Ответ на: комментарий от Booster

Так на то он и временный, что создаётся, делает своё дело и уничтожается. Чего тут бредового?

В том то и дело что он уничтожается до того как сделает своё дело, ниже идёт вызов метода show(), но к этому моменту объект самоликвидировался.

ferrum2688
() автор топика
Ответ на: комментарий от ferrum2688

>destr1adress0xbfa761e4 //Вызвали деструктор G

constr2adress0xbfa761e8 //Создали временный объект

//Скопировали временный объект в G. (Этим занимается оператор «=»)

destr2adress0xbfa761e8 //Удалили временный объект

0xbfa761e4 //Вызвали std::cout<<&G<<std::endl;

G //std::cout<<«G»<<std::endl;

2 // Ну и тут вызвали show() для G

Шониясна?

AF ★★★
()
Ответ на: комментарий от ferrum2688

>В том то и дело что он уничтожается до того как сделает своё дело, ниже идёт вызов метода show(), но к этому моменту объект самоликвидировался.
show ведь вызывается для не временного, так? Или у Вас, или у нас недопонимание. Объясните по-порядку, чего Вы добиваетесь и чего ожидаете.

Booster ★★
()
Ответ на: комментарий от Booster


destr2adress0xbfa761e8//вызвался деструктор для объекта, цифра два его условный идентификатор
0xbfa761e4
G
2//а вот для него вызвался метод show, цифра 2 указывает что это тот самый объект

я добивался повторно использовать статические/автоматические объекты, выше мне указали как это делать, и что то что я делаю так делать нельзя. Но по поводу вашего «Чего тут бредового?» я и ответил, что вывод в консоль бред. И если судить по листингу то метод шоу вызвался для уже уничтоженного объекта, который я не уничтожал, он сам почему то уничтожился.

ferrum2688
() автор топика
Ответ на: комментарий от AF

Шониясна?

как раз сегодня кое с чем разбирался, плюс ваш ответ, всё, теперь всё понятно.

ferrum2688
() автор топика
Ответ на: комментарий от Booster

извиняюсь, поторопился с ответом, действительно вывод не бред.

ferrum2688
() автор топика

> у меня проблемы с англ

сорри за оффтопик. Придумал исконно русский термин для деструктора: пшик

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

>сорри за оффтопик. Придумал исконно русский термин для деструктора: пшик

Боюсь даже представить твой перевод для исключений ))

AF ★★★
()

РЕШЕНО НА 95%

Поторопился с постановкой тега решено, только сейчас нашёл хороший ответ на свои вопросы

1. Деструктор вызывается как обычная функция, просто нужно помнить что он также автоматически вызывается в определённых частях программы

2. Это не бред

3. Чтобы повторно вызвать конструктор нужно вместо G=MyString(3)(что работает медленно, требует определения оператора = и это не повторный вызов конструктора) написать:
G.~MyString();
new(&G)MyString(3);

последняя строчка как мне кажется почти эквивалентна повторному вызову конструктора, хотя возможно существует и родной с++ метод



ferrum2688
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.