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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Принимаем объект исключения по ссылке или значению, Где почитать более детальней 
:(
    Опции темы
EvilsInterrupt
Дата 30.6.2009, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



Есть код:

Код

#include <iostream>

/*----------------------------------------------------------------------------*/
using std::cout;
using std::endl;
/*----------------------------------------------------------------------------*/

typedef struct BaseException {
  BaseException(char * t, int c) {
    text =t; code =c;
    cout << "BaseException" << endl;
  }
  virtual void PrintfErrMsg() {
    cout << "text: " << text << "  code: " << code << endl;
  }
  char * text;
  int    code;
} *PBaseException;

typedef struct SimpleException : public BaseException {
  SimpleException(char * t, int c, int a) :
    BaseException(t,c)
  {
    addon = a;
    cout << "SimpleException" << endl;
  }
    virtual void PrintfErrMsg() {
      cout << "text: " << text << "  code: " << code <<
              "  addon: " << addon << endl;
    }
  int addon;
} *PSimpleException;

/*----------------------------------------------------------------------------*/
int main()
{
  try
  {
    throw ( SimpleException("HZ", 1, 2) );
  }
  catch (BaseException& e) /// Label
  {
    e.PrintfErrMsg();
    return(1);
  }
  return(0);
}


Если в "Label" что помечена комментариями вызову не по ссылке, а по значению то PrintfErrMsg будет от базового класса BaseException , если по ссылке то от потомка SimpleException. 

Мне хочется более детально вникнуть в след. вопросы:
1. Как вызываются и у кого конструкторы копий, чтобы такой результат был ?
2. Кто удаляет объект исключения при прием по ссылке или по значению, а ведь можно объект и по throw new созадать , как тогда будет убиваться объект ?

Вобщем вопросов много, мне бы ключевые слова, которые нужно искать в книге Страуструпа, пока читаю главу 14 про исключения, но не особо въехал
PM MAIL WWW ICQ Jabber   Вверх
azesmcar
Дата 30.6.2009, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(EvilsInterrupt @  30.6.2009,  11:22 Найти цитируемый пост)
Если в "Label" что помечена комментариями вызову не по ссылке, а по значению то PrintfErrMsg будет от базового класса BaseException , если по ссылке то от потомка SimpleException. 

а что тут странного? PrintfErrMsg виртуальная функция, в случае поимки исключения по значению - объект копируется в объект типа базового класса.
А можно узнать - зачем ловить исключения по значению?
PM   Вверх
EvilsInterrupt
Дата 30.6.2009, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



2 azesmcar :
Вопрос не в странности "зачем ловить?", а вопрос как вникнуть в "Мне хочется более детально вникнуть в след. вопросы:"

То что я привел этот код, это всего лишь для того чтобы показать что мне интересно! ;) Понятно что на практике ни один умо-имеющий программер не будет принимать по значению объект ,когда мог быть передан потомок. Но т.к. изучаю азы, мне интересно пока все тонкости и нюансы ;)

PM MAIL WWW ICQ Jabber   Вверх
azesmcar
Дата 30.6.2009, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(EvilsInterrupt @  30.6.2009,  11:22 Найти цитируемый пост)
2. Кто удаляет объект исключения при прием по ссылке или по значению, а ведь можно объект и по throw new созадать , как тогда будет убиваться объект ?

а кто удаляет объект когда ты пишешь
Код

int a;

?
Этот объект имеет automatic storage duration и он автоматически удаляется при покидании блока. Если создать объект исключения с помощью new, тогда он имеет dynamic storage duration и забота об удалении возлагается на твои плечи.

Цитата(EvilsInterrupt @  30.6.2009,  11:31 Найти цитируемый пост)
Вопрос не в странности "зачем ловить?", а вопрос как вникнуть в "Мне хочется более детально вникнуть в след. вопросы:"

ответ на вопрос в том, что вызывается копирующий конструктор для BaseException и соответственно создается объект типа BaseException и функция будет вызвана для него.

Это сообщение отредактировал(а) azesmcar - 30.6.2009, 11:35
PM   Вверх
EvilsInterrupt
Дата 30.6.2009, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



не совсем так, когда пишу:
Код

int a;

то как правило создается стековый фрэйм, а-ля:
Код

push ebp
mov  ebp,esp
sub  esp,4

и в прологе обычный add esp,4

Это все понятно и легко!
Но в случае new выделяется память под создаваемый объект, значит он должен быть убит, т.е. кто-то должен вызвать delete exception_obj; и тут обыкновенным sub esp,4 мы убьем просто локальную переменную храняющую адрес, но никак не сам объект !!!

Мне интересно как убивается сам объект ! ;)
PM MAIL WWW ICQ Jabber   Вверх
azesmcar
Дата 30.6.2009, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(EvilsInterrupt @  30.6.2009,  11:37 Найти цитируемый пост)
не совсем так, когда пишу:

так. Это был ответ на вопрос
Цитата

Кто удаляет объект исключения при прием по ссылке или по значению

на этот вопрос я ответил далее
Цитата

а ведь можно объект и по throw new созадать , как тогда будет убиваться объект ?


Цитата(azesmcar @  30.6.2009,  11:31 Найти цитируемый пост)
Если создать объект исключения с помощью new, тогда он имеет dynamic storage duration и забота об удалении возлагается на твои плечи.

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

Цитата(EvilsInterrupt @  30.6.2009,  11:37 Найти цитируемый пост)
Мне интересно как убивается сам объект ! ;) 

вызовом деструктора.

Цитата(EvilsInterrupt @  30.6.2009,  11:37 Найти цитируемый пост)
Но в случае new выделяется память под создаваемый объект, значит он должен быть убит, т.е. кто-то должен вызвать delete exception_obj; и тут обыкновенным sub esp,4 мы убьем просто локальную переменную храняющую адрес, но никак не сам объект !!!

никто за тебя этого не сделает (вру, смарт поинтеры сделают smile но их еще использовать надо).
Если ты динамически выделил память - значит освобождай ее. delete exception_obj должен писать ты.

Это сообщение отредактировал(а) azesmcar - 30.6.2009, 11:42
PM   Вверх
zim22
Дата 30.6.2009, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

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



Цитата(EvilsInterrupt @  30.6.2009,  11:37 Найти цитируемый пост)
 и тут обыкновенным sub esp,4 мы убьем просто локальную переменную храняющую адрес, но никак не сам объект

с чего вы взяли что при вызове delete будут вызываться именно эти ассемблерные команды?

Цитата(EvilsInterrupt @  30.6.2009,  11:37 Найти цитируемый пост)
Мне интересно как убивается сам объект ! ;)

Цитата(azesmcar @  30.6.2009,  11:31 Найти цитируемый пост)
automatic storage duration ... автоматически удаляется при покидании блока. Если создать объект исключения с помощью new, тогда он имеет dynamic storage duration и забота об удалении возлагается на твои плечи.

сначала оператор delete  вызывает деструктор объекта.  а потом вызвается функция operator delete, которая подчищает память за объектом.



--------------------
PM MAIL   Вверх
EvilsInterrupt
Дата 30.6.2009, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



Вопросы:

1) Если сгенерировали потомка SimpleException и не использовали оператор new. В операторе catch поймали по значению , то вызовется PrintfErrMsg от базового класса, не смотря на то что создан потомок! Значит вызван конструктор копий такой, что создал указатель на виртуальную ф-цию базового класса ! Вопрос какого хрена ? Почему так ? + Ко всему кто убьет объект в этом catch ?

2) Если повторили тоже самое что и в п.1 ,но приняли по ссылке в операторе catch , то значит был вызван конструктор и он почему то присвол указателю вирт ф-ции PrintfErrMsg  на вариант этой ф-ции в SimpleException , почему ? Какого черта ? Потом, кто убивает объект переданный в catch ?

3) Если мы при генерации воспользовались new SimpleException, то я должен:
 - в этом классе сделать виртуальным деструктор
 - в catch теле вызвать самостоятельно delete e; ?
все верно думаю в п.3 ?

Уточняю еще, пока не скопилировалось понимание ;)
PM MAIL WWW ICQ Jabber   Вверх
zim22
Дата 30.6.2009, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

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



Цитата(EvilsInterrupt @  30.6.2009,  11:59 Найти цитируемый пост)
1) Если сгенерировали потомка SimpleException и не использовали оператор new. В операторе catch поймали по значению , то вызовется PrintfErrMsg от базового класса, не смотря на то что создан потомок!

при передаче объекта производного класса в фунцию, которая принимает в качестве параметра объект базового класса по значению - объект производного класса будет "урезан" до объекта базового класса. 
***
EvilsInterrupt, снабдите диагностическими сообщениями вызовы конструкторов/деструкторов.
сами и увидите как всё происходит. 
Код

virtual ~BaseException() { 
    cout << "~BaseException" << endl;
  }


Это сообщение отредактировал(а) zim22 - 30.6.2009, 12:11


--------------------
PM MAIL   Вверх
xvr
Дата 30.6.2009, 12:13 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Можешь грубо считать, что параметр catch - это формальный аргумент процедуры. А твой объект в throw - это фактический параметр. А сам блок catch - это вызов процедуры с параметром. Все манипуляции с параметрами (и объектами) будут такими же.

PM MAIL   Вверх
GoldFinch
Дата 30.6.2009, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(EvilsInterrupt @  30.6.2009,  12:59 Найти цитируемый пост)
Вопросы:

1) при передаче объекта класса Foo по значению вызывается копирующий конструктор Foo(Foo&)
при этом тело объекта находится в стеке, его деструктор будет вызван при завершении "функции" catch,  тело объекта будет удалено ret xx если __stdcall или вызвавшим ее кодом если это __cdecl
"не использовали оператор new" : оригинальный объект, который копировался, живет в стековом фрейме функции (или самого try-catch если у него свой фрейм), при выходе из функции будет вызван его деструктор, а mov esp,ebp удалит его тело

2) Если передали по ссылке, копирования нет, после try-catch будет восстановлен esp (mov esp,ebp) и тело объекта удалится. Про деструктор - хз

3) все так

скомпилил бы, заглянул в IDA, все бы увидел и нам рассказал %)

Это сообщение отредактировал(а) GoldFinch - 30.6.2009, 14:13
PM MAIL ICQ   Вверх
EvilsInterrupt
Дата 30.6.2009, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



>>скомпилил бы, заглянул в IDA, все бы увидел и нам рассказал %)
влом ) пока задал и жду ответа, делаю декомпиляцию виртуализованного кода от RLPack 1.20.1f мозг выносит напрочь... ;) Уж не ругайтесь сильно ;)

Это сообщение отредактировал(а) EvilsInterrupt - 30.6.2009, 13:48
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 30.6.2009, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(EvilsInterrupt @  30.6.2009,  10:22 Найти цитируемый пост)
Если в "Label" что помечена комментариями вызову не по ссылке, а по значению то PrintfErrMsg будет от базового класса BaseException , если по ссылке то от потомка SimpleException. 

Ваши вопросы не связаны с исключениями - такое поведение будет и при обычном вызове функции.
1. При передаче по копии используется конструктор типа указанного в параметре функции.
2. Копия удаляется при выходе из функции.




--------------------
PM MAIL WWW   Вверх
EvilsInterrupt
Дата 2.7.2009, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



Что если в операторе throw при создании объекта в конструкторе класса исключения, к примеру SimpleException описываемого выше, произошла бага и он не создался ? Как это разруливается ?
PM MAIL WWW ICQ Jabber   Вверх
xvr
Дата 2.7.2009, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Никак не разруливается. Будет вызвана функция terminate, что приведет к abort'у программы

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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