Уничтожение лок. переменных!!!???
От: avch  
Дата: 03.10.03 08:16
Оценка:
Привет всем!!!
Вот такой код в VC6 билдится да еще и без ошибок RT выполняется:

#include <iostream.h>

class C1 {
public:
    C1() {};
    void F1() { cout << "C1.F1()\n"; };
 ~C1() { cout << "~C1()\n"; };
};

class C2 {
public:
     C1 c1; 
     C2()  {};
  ~C2() {};
};

void NullC1(C2& c2)
{
    C1 c1;
    c2.c1 = c1;
};

int main(void) {
    C2 c2;
    c2.c1.~C1(); <-------------------+
    NullC1(c2);                  +
    c2.c1.F1();                  +
     return 0;                    +
};                                   +
+
и выдает такое: +
~C1() // c этим вроде все понятно --+
~C1() // и с этим вроде тоже (вызывается компилом при выходе из NullC1() )
C1.F1() // по моему бред какойто, ведь с1 уже нет, выходит что конструктор и деструктор это простые
// процедуры или я что-то непонимаю???
~C1() // тоже самое
_____________________
Заранее благодарен за ответ....
Re: Уничтожение лок. переменных!!!???
От: Lorenzo_LAMAS  
Дата: 03.10.03 08:50
Оценка: +1
Здравствуйте, Lorenzo_LAMAS, Вы писали:

Вообще такое писать не стоит. Зачем такие извращения.
Но что непонятного в том, что ты получил?

int main()
{
   c2.c1.~C1();// - ты вызвал здесь деструктор (само по себе вот это уже дерьмо). 
  /*далее ты передал c2 в функцию,
   которая берет, и разрушенному подобъекту пытается присвоить. Далее временный объект,
   созданный в функции, разрушается. Далее, ты вызываешь функцию - но это уже не важно,
   потому как уже к этому моменты твоя программа имеет undefined behavior
   Заканчивается время жизни c2 - по завершении main, вызывается деструктор для с2.с1 - 
   повторное разрушение изуродованного объекта.*/
   return 0;
}
Of course, the code must be complete enough to compile and link.
Re[2]: Уничтожение лок. переменных!!!???
От: avch  
Дата: 03.10.03 09:04
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Здравствуйте, Lorenzo_LAMAS, Вы писали:


L_L>Вообще такое писать не стоит. Зачем такие извращения.

L_L>Но что непонятного в том, что ты получил?

L_L>
L_L>int main()
L_L>{
L_L>   c2.c1.~C1();// - ты вызвал здесь деструктор (само по себе вот это уже дерьмо). 
L_L>  /*далее ты передал c2 в функцию,
L_L>   которая берет, и разрушенному подобъекту пытается присвоить. Далее временный объект,
L_L>   созданный в функции, разрушается. Далее, ты вызываешь функцию - но это уже не важно,
L_L>   потому как уже к этому моменты твоя программа имеет undefined behavior
L_L>   Заканчивается время жизни c2 - по завершении main, вызывается деструктор для с2.с1 - 
L_L>   повторное разрушение изуродованного объекта.*/
L_L>   return 0;
L_L>}
L_L>

Функция не присваивает разрушенному объекту, если вы заметили:

int main(void) {
    C2 c2;
    c2.c1.~C1(); // здесь уничтожается объект с1 который есть член с2,
// и почему это вызов деструктора дерьмо, нивкаких руководствах этого ненаписано,
// и то что вызываются первые 2 деструктора - это нормально, но дальше уже мне непонятно...
// Понятно что так писать нельзя, передавать кудато во внешний код локальный объект, но
// я это и хотел проверить, а что произойдет, и ничего не произошло - функция F1() вызвалась
// и сработала, а этого не должно быть
    NullC1(c2);
    c2.c1.F1(); //??????
     return 0;
};
Re[2]: Уничтожение лок. переменных!!!???
От: alexandrov_alex США  
Дата: 03.10.03 09:11
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

LL> Вообще такое писать не стоит. Зачем такие извращения.

LL> Но что непонятного в том, что ты получил?
LL>
LL>
 LL> int main()
 LL> {
 LL>    c2.c1.~C1();// - ты вызвал здесь деструктор (само по себе вот это
 LL> уже дерьмо). /*далее ты передал c2 в функцию,
 LL>    которая берет, и разрушенному подобъекту пытается присвоить. Далее
 LL> временный объект,
 LL>    созданный в функции, разрушается. Далее, ты вызываешь функцию - но
 LL> это уже не важно,
 LL>    потому как уже к этому моменты твоя программа имеет undefined
 LL> behavior
 LL>    Заканчивается время жизни c2 - по завершении main, вызывается
 LL> деструктор для с2.с1 - 
 LL>    повторное разрушение изуродованного объекта.*/
 LL>    return 0;
 LL> }
 LL>


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

-- Всего хорошего!
-- Alex Alexandrov, e-mail: alexandrov_alex@fromru.com
Posted via RSDN NNTP Server 1.7 "Bedlam"
It's kind of fun to do the impossible (Walt Disney)
Re[3]: Уничтожение лок. переменных!!!???
От: Lorenzo_LAMAS  
Дата: 03.10.03 09:15
Оценка:
Твоя функция принимает аргумент по ссылке (если б принимала по значению тоже было б плохо), в ней ты присваиваешь разрушенному оьбъекту.
Of course, the code must be complete enough to compile and link.
Re[3]: Уничтожение лок. переменных!!!???
От: Lorenzo_LAMAS  
Дата: 03.10.03 09:17
Оценка:
Тут ситуация немного другая, с аллокаторами не схожая. Вызвается деструктор для объекта, который не является полным объектом, а часть другого объекта.
Of course, the code must be complete enough to compile and link.
Re[3]: Уничтожение лок. переменных!!!???
От: Lorenzo_LAMAS  
Дата: 03.10.03 09:28
Оценка:
Вообще, похоже, про требования к объекту быть complete — я загнул, он, в стандарте сказано только про most-derived
Of course, the code must be complete enough to compile and link.
Re[4]: Уничтожение лок. переменных!!!???
От: alexandrov_alex США  
Дата: 03.10.03 09:43
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

LL> Тут ситуация немного другая, с аллокаторами не схожая. Вызвается

LL> деструктор для объекта, который не является полным объектом, а часть
LL> другого объекта.

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

P.S. Все-таки программирование — интересная область. Каждый раз, когда пишу "нельзя, невозможно, отсутствует", внутренне вздрагиваю от мысли: "Ну что, Алексей, сейчас тебе объяснят, кто здесь верблюд". И тем не менее, все равно пишу... Пусть объяснят. Ведь так интересней...

-- Всего хорошего!
-- Alex Alexandrov, e-mail: alexandrov_alex@fromru.com
Posted via RSDN NNTP Server 1.7 "Bedlam"
It's kind of fun to do the impossible (Walt Disney)
Re[3]: Уничтожение лок. переменных!!!???
От: avch  
Дата: 03.10.03 09:45
Оценка:
Здравствуйте, alexandrov_alex, Вы писали:

_>Здравствуйте, Lorenzo_LAMAS, Вы писали:


LL>> Вообще такое писать не стоит. Зачем такие извращения.

LL>> Но что непонятного в том, что ты получил?
LL>>
LL>>
 LL>> int main()
 LL>> {
 LL>>    c2.c1.~C1();// - ты вызвал здесь деструктор (само по себе вот это
 LL>> уже дерьмо). /*далее ты передал c2 в функцию,
 LL>>    которая берет, и разрушенному подобъекту пытается присвоить. Далее
 LL>> временный объект,
 LL>>    созданный в функции, разрушается. Далее, ты вызываешь функцию - но
 LL>> это уже не важно,
 LL>>    потому как уже к этому моменты твоя программа имеет undefined
 LL>> behavior
 LL>>    Заканчивается время жизни c2 - по завершении main, вызывается
 LL>> деструктор для с2.с1 - 
 LL>>    повторное разрушение изуродованного объекта.*/
 LL>>    return 0;
 LL>> }
 LL>>


_>В целом все так, только насчет дерьма не согласен. Деструкторы иногда приходится вызывать явно, например, при создании собственного аллокатора объектов. Как всегда, надо просто понимать, что это за собой влечет и зачем это делается...


_>-- Всего хорошего!

_>-- Alex Alexandrov, e-mail: alexandrov_alex@fromru.com
Ладно, напишем подругому...

#include <iostream.h>

class C1 {
public:
    C1(int _m=0):m(_m) {};
     int m;
    void F1() { cout << "C1.F1("<<m<<")\n"; };
    C1& operator=(C1& c) { 
        this->~C1();
        return c; };
 ~C1() { cout << "~C1("<<m<<")\n"; };
};

class C2 {
public:
     C1 c1; 
     C2()  {};
  ~C2() {};
};

void NullC1(C2& c2)
{
    C1 c1(1);
    c2.c1=c1; // здесь происходит замена объекта с1, который сконтруировался
 // автоматически при создании с2, локальным с1
};

int main(void) {
    C2 c2;
    NullC1(c2);
    c2.c1.F1();
     return 0;
};

выход проги есть:
~C1(0) // это понятно, вызывается внутри оператора
~C1(1) // это тоже, внутри ф-ии NullC1()
C1.F1(0) // а вот это уже совсем непонятно, объект полностью сохранился с его членами-даными
~C1(0) // вызов деструктора это подтверждает...
Re[5]: Уничтожение лок. переменных!!!???
От: avch  
Дата: 03.10.03 09:49
Оценка:
Здравствуйте, alexandrov_alex, Вы писали:

_>Здравствуйте, Lorenzo_LAMAS, Вы писали:


LL>> Тут ситуация немного другая, с аллокаторами не схожая. Вызвается

LL>> деструктор для объекта, который не является полным объектом, а часть
LL>> другого объекта.

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


_>P.S. Все-таки программирование — интересная область. Каждый раз, когда пишу "нельзя, невозможно, отсутствует", внутренне вздрагиваю от мысли: "Ну что, Алексей, сейчас тебе объяснят, кто здесь верблюд". И тем не менее, все равно пишу... Пусть объяснят. Ведь так интересней...


_>-- Всего хорошего!

_>-- Alex Alexandrov, e-mail: alexandrov_alex@fromru.com

Никто вызов деструктора обойти и не пытается, просто не понятно почему программа работает а не выдает
RT ошибок...
Re[4]: Уничтожение лок. переменных!!!???
От: Lorenzo_LAMAS  
Дата: 03.10.03 09:53
Оценка:
Ты для кого такое пишешь? Офигенно! Я вызвал оператор присваивания, а у меня в результате его работы объект незаметно подох. Чтоб наглядней было, пиши уж что-то типа такого

class A
{
public:
   A():p_(new int)
   {
   }
   A(const A &):p_(new int)
   {
   }
   ~A()
   {
       delete p_;
   }
   A & operator = (const A &)
   {
       this->~A();

       return (*this);
   }
};


и наслаждайся. никакой замены не происходит c2.c1 = c1; — бред — разрушаешь один объект и возвращаешь ссылку на другой, чего это ты хочешь добиться?
Of course, the code must be complete enough to compile and link.
Re[6]: Уничтожение лок. переменных!!!???
От: Lorenzo_LAMAS  
Дата: 03.10.03 10:00
Оценка:
А какие по-твоему RT ошибки она тебе должна выдать при такой примитивной прогармме? Добавь операторы new/delete и наслаждайся
Of course, the code must be complete enough to compile and link.
Re[7]: Уничтожение лок. переменных!!!???
От: Анатолий Широков СССР  
Дата: 03.10.03 10:05
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>А какие по-твоему RT ошибки она тебе должна выдать при такой примитивной прогармме? Добавь операторы new/delete и наслаждайся


А чем наслаждаться-то?
Re[5]: Уничтожение лок. переменных!!!???
От: avch  
Дата: 03.10.03 10:05
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Ты для кого такое пишешь? Офигенно! Я вызвал оператор присваивания, а у меня в результате его работы объект незаметно подох. Чтоб наглядней было, пиши уж что-то типа такого


L_L>
L_L>class A
L_L>{
L_L>public:
L_L>   A():p_(new int)
L_L>   {
L_L>   }
L_L>   A(const A &):p_(new int)
L_L>   {
L_L>   }
L_L>   ~A()
L_L>   {
L_L>       delete p_;
L_L>   }
L_L>   A & operator = (const A &)
L_L>   {
       this->>~A();

L_L>       return (*this);
L_L>   }
L_L>};
L_L>


L_L>и наслаждайся. никакой замены не происходит c2.c1 = c1; — бред — разрушаешь один объект и возвращаешь ссылку на другой, чего это ты хочешь добиться?


Это я написал как пример чтобы разобраться, я специально удаляю объект,
поэтому мне и не понятно почему ф-ия F1() вызывается и срабатывает ведь
этого не должно быть, вот что мне интересно...
Re[8]: Уничтожение лок. переменных!!!???
От: Lorenzo_LAMAS  
Дата: 03.10.03 10:06
Оценка:
Так ведь ему ж нужно наглядное проявление ошибок.
Of course, the code must be complete enough to compile and link.
Re[6]: Уничтожение лок. переменных!!!???
От: Lorenzo_LAMAS  
Дата: 03.10.03 10:08
Оценка:
Так это тебе просто повезло, что она "работает".
Of course, the code must be complete enough to compile and link.
Re[7]: Уничтожение лок. переменных!!!???
От: avch  
Дата: 03.10.03 10:08
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>А какие по-твоему RT ошибки она тебе должна выдать при такой примитивной прогармме? Добавь операторы new/delete и наслаждайся


Дак с указателями как раз RT ошибки и выдаются а статические объекты как их не уничтожай работают...
Re[8]: Уничтожение лок. переменных!!!???
От: Аноним  
Дата: 03.10.03 10:18
Оценка:
Ну а что, по-твоему, с ними должно случиться?

[ccode]
class A
{
public:
int m_;
};

void fun()
{
A a;
a.~A();
std::cout<<a.m<<std::endl;
}

[ccode]

Что тут может случиться? Программа содержит неопределенное поведение, но, однако, какие RT ошибки тут по твоему могут быть?
Re[7]: Уничтожение лок. переменных!!!???
От: avch  
Дата: 03.10.03 10:25
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Так это тебе просто повезло, что она "работает".

Интересное везение....
Тогда глянь на это:

#include <iostream.h>

class C1 {
public:
    C1(int _m=0):m(_m) {};
     int m;
    void F1() { cout << "C1.F1("<<m<<")\n"; };
 ~C1() { cout << "~C1("<<m<<")\n"; };
};

class C2 {
public:
     C1 c1; 
     C2()  {};
     void F2() {cout << "C1.F1("<<c1.m<<")\n";};
  ~C2() {};
};


int main(void) {
    C2 c2;
    c2.~C2();
    c2.F2();
     return 0;
};

результат:
~C1(0)
C1.F1();
~C1(0);
Re[9]: Уничтожение лок. переменных!!!???
От: avch  
Дата: 03.10.03 10:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну а что, по-твоему, с ними должно случиться?


А>
А>class A
А>{
А>public:
А>    int m_;
А>};

А>void fun()
А>{
А>    A a;
А>    a.~A();
А>    std::cout<<a.m<<std::endl;
А>}

А>[ccode]

А>Что тут может случиться? Программа содержит неопределенное поведение, но, однако, какие RT ошибки тут по твоему могут быть? 

Непонятно, почему состояние объекта разрушается а его структура в памяти остается??? Как то это убого, зачем
оставлять объект в памяти если он уничтожен деструкторм

вот код

[ccode]

class A
{
  A() {};
  F() {};
  ~A() {};
};

void main()
{
  A a;
  a.F();
 a.~A();
  a.F(); // работает, вот бред 
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.