Страница 4 из 6

Re: Вызов виртуальных методов в конструкторах

Добавлено: 26 май 2009, 16:23
Hawk
Как я понимаю (транслировав все теги) ваше утверждение следует из описания конструктора _employee__ctor ?

Т.е. вот этого -

Код: Выделить всё

_employee__ctor( employee *this ) // Конструктор по умолчанию, генерируемый
{ // компилятором.

_storable_ctor(); // Базовые классы инициализируются 
                       // в первую очередь.
_vtable = _employee_vtable; // Создается таблица виртуальных функций.
}
Т.к. _vtable = _employee_vtable; последняя строчка в этом коде из этого и можно сделать вывод что таблица виртуальных методов "заполняется" после, а точнее в конце конструктора?

Хорошо, но почему нельзя утверждать что эта строчка стоит в начале конструктора? Так как конструктор класса employee не объявлен и сгенерирован по умолчанию, о чем даже есть комментарий, значит он пустой. Значит наверняка нельзя сказать куда запишутся строчки и например вызовы виртуальных функций, если мы их добавим в этот конструктор.

Кроме того первым делом тут вызывается конструктор базового класса storage который-то описан и в оригинале содержит единственную строчку -

Код: Выделить всё

storable::storable ( void ) { stuff = 0; }
т.е. stuff = 0; И как далее пишет Ален Голуб вот во что превращается этот конструктор -

Код: Выделить всё

_storable__ctor( void ) // конструктор
{
_vtable = _storable__vtable; // Эту строку добавляет компилятор
stuff = 0; // Эта строка из исходного кода.
}
по-моему все очевидно и респект ему

Re: Вызов виртуальных методов в конструкторах

Добавлено: 26 май 2009, 16:59
Airhand
Hawk писал(а):Как я понимаю (транслировав все теги) ваше утверждение следует из описания конструктора _employee__ctor ?
Да. И не выкай мне.
Хорошо, но почему нельзя утверждать что эта строчка стоит в начале конструктора? Так как конструктор класса employee не объявлен и сгенерирован по умолчанию, о чем даже есть комментарий, значит он пустой. Значит наверняка нельзя сказать куда запишутся строчки и например вызовы виртуальных функций, если мы их добавим в этот конструктор.
Нельзя так переставлять строки кода. Слова в песне не меняются местами.

.

Добавлено: 26 май 2009, 17:39
BBB
Airhand писал(а):Да. И не выкай мне.
"Да кто ты такой, чтобы мне выкать!? Мы что, с тобой на врагершафт пили?!?!" :lol:
Airhand писал(а):Нельзя так переставлять строки кода. Слова в песне не меняются местами.
А никто ничего и не переставлял. Прочтите еще раз, что написал Hawk, и что он имел в виду. А именно то, что если между началом и концом расположено что-то ОДНО, то с таким же полным правом можно сказать, что это "что-то" находится "сразу после начала". А не "сразу перед концом".

Re: Вызов виртуальных методов в конструкторах

Добавлено: 26 май 2009, 18:44
Romeo
&quot писал(а):Инициализация - это, прежде всего, выделение памяти под объкт. А выделение памяти и внесение изменений в таблицу - это разные вещи.
Я понял источник нашего непонимания. Он в том, что под инициализацией ты видишь выделение памяти. На самом деле инициализация - это процесс первоначальной (инициализирующей) простановки данных в объект. Инициализация не имеет отношения к выделению памяти. Эти два процесса можно разнести, например, воспользовавшись третьей формой оператора new.

Кстати, я тут перечитал статью, и понял, что вынужден извиниться перед Аланом Голубом, точнее даже не перед ним, так как во всём виноват переводчик. Я, расплёвываясь в разные стороны от досады, окончил читать статью вот на этой фразе.
&quot писал(а): ... и указатель в таблице виртуальной функции переписывается
Именно эта фраза и возмутила меня до глубины души, так как таблицы неизменяема.

Огромный респект переводчику. Текст на самом деле должен быть следующим, тогда он обретает смысл:
&quot писал(а): ... и указатель на таблицу виртуальных функций переписывается так, чтобы он указывал на таблицу производного класса.
Там ещё следует исправить несколько ляпов, который также остаются на совести переводчика. Например текст, прямо перед предыдущим текстом:
&quot писал(а): которая добавляет таблицу этой виртуальной функции к своей таблице и выполняется.
Следует перефразировать целиком.
&quot писал(а): которая записывает в указатель на таблицу виртуальных функций адрес своей таблицы и выполняется.
После этой поправки статья целиком повторяет то, что я описал в своём посте две страницы назад, ещё до того, как узнал об этом писателе. То есть мы возвращаемся к выведенной ранее последовательности вызовов:

Код: Выделить всё

vptr = &Table(A)
A()
vptr = &Table(B)
B()
vptr = &Table(C)
C()
Теперь, дорогой Airhand, укажи мне, плиз, где ты нашёл в статье упоминание о том, что указатель на таблицу перезаписывается лишь после выполнения тела конструктора?

Далее по приведённому коду.
&quot писал(а): _vtab *_vtable; // Генерируемое компилятором поле данных.
Ха-ха, уже не возникает вопросов почему первые четыре байта в объекте - это указатель на таблицу виртуальных функций? Почему же по-прежнему критикуешь мою программу? :)
&quot писал(а): _employee__ctor( employee *this ) // Конструктор по умолчанию, генерируемый
{ // компилятором.
_storable_ctor(); // Базовые классы инициализируются
// в первую очередь.
_vtable = _employee_vtable; // Создается таблица виртуальных функций.
}
Порядок вызова выдумал ты. На самом деле он обратный, это доказывает моя программа и этому нет противоречий в статье.

А вот это вообще шедевр.
&quot писал(а): _vtable = _employee_vtable; // Создается таблица виртуальных функций.
Я же тебе ещё раньше написал, чтобы ты писал побольше кода и комментариев лично от себя. Я бы тебе давно указал в каком именно месте ты неверно используешь терминологию или просто ошибаешься и наш спор даным давно бы завершился. Открою тебе секрет. В той строке, напротив который ты написал "Создаётся таблица" на самом деле таблица не создаётся. В этой строке происходит ПРИСВАИВАНИЕ УКАЗАТЕЛЯ НА ТАБЛИЦУ. Это абсолютно не одно и то же. Вот небольшой ликбез с комментариями.

Код: Выделить всё

int i; // Создание переменной
int *p; // Создание указателя
p = &i; // Установка указателя p на область памяти i
То же самое касается и нашего случая. На момент выполнения квотированной строки и указатель, и таблица уже созданы. Указатель - на этапе создания объекта. Таблица - вообще до входа в main на этапе загрузки исполняемого файла в память. В указанной же строке происходит ПРИСВАИВАНИЕ УКАЗАТЕЛЯ на таблицу, а не СОЗДАНИЕ таблицы. Во время работы всей программы эта таблица не меняется.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
[offtop] Hawk, рад видеть тебя. Где пропадал так долго? [/offtop]

Re: Вызов виртуальных методов в конструкторах

Добавлено: 26 май 2009, 20:16
Airhand
Romeo писал(а):А вот это вообще шедевр.
Это не мой код и комментарии к нему. Так что потоки своей желчи изливай не мне. Если бы ты внимательно читал главу, то ты бы заметил и код и комментарии.
Я понял источник нашего непонимания. Он в том, что под инициализацией ты видишь выделение памяти. На самом деле инициализация - это процесс первоначальной (инициализирующей) простановки данных в объект. Инициализация не имеет отношения к выделению памяти. Эти два процесса можно разнести, например, воспользовавшись третьей формой оператора new.
Может быть.
После этой поправки статья целиком повторяет то, что я описал в своём посте две страницы назад, ещё до того, как узнал об этом писателе. То есть мы возвращаемся к выведенной ранее последовательности вызовов:
Твоя схема в любом случае - неверная. Присваивание происходит внутри конструктора.
Порядок вызова выдумал ты. На самом деле он обратный, это доказывает моя программа и этому нет противоречий в статье.
Может я и не прав с порядком, но твоя схема вообще неверная.

Re: Вызов виртуальных методов в конструкторах

Добавлено: 26 май 2009, 21:00
Hawk
[offtop] я тоже вас всех люблю =) а вообще все времени нет зайти сюда, хотя нотификации бывает читаю

И вообще чего вы паритесь, натуральный тролль какой-то -
Airhand писал(а): Твоя схема в любом случае - неверная.
...
Может я и не прав с порядком, но твоя схема вообще неверная.
и т.д. в общем вы все будете не правы полюбому. Еслиб человек хотел что-то узнать, послушал бы что ему говорят. Или в свой же пример посмотрел и подумал о чем там говорится.
Так что бросайте вы это дело и идите гулять, погода шепчет =)!

.

Добавлено: 26 май 2009, 21:02
BBB
Airhand писал(а):Твоя схема в любом случае - неверная. Присваивание происходит внутри конструктора.
ВО ВРЕМЯ выполнения оператора begin конструктора - это ВНЕ или ВНУТРИ конструктора?

Re: Вызов виртуальных методов в конструкторах

Добавлено: 26 май 2009, 21:21
Romeo
&quot писал(а):Это не мой код и комментарии к нему.
Согласен, я пропустил комментарий в статье. Это ошибка либо Голуба, либо переводчика. Но это не оправдывает тебя :) Во всех своих предыдущих постах ты использовал именно эту терминологию. Если бы ты думал иначе, то исправил бы ошибку, когда копировал код из статьи на форум. Теперь пробел в непонимании устранён и это хорошо.
&quot писал(а):Так что потоки своей желчи изливай не мне
Нет, я уже успокоился :) Я болезненно реагирую лишь в том случае, когда человек, обладающий недостаточными знаниями пытается показать насколько он "крут". Сейчас ты перестал красоваться и я вижу, что стал читать сторонние статьи и анализировать написанное нами, чтобы вести полемику. Также ты пропускаешь те мои ответы, которые бесспорны, беря их себе на заметку. Это меня успокоило и я наоборот хочу тебе помочь.
&quot писал(а):Твоя схема в любом случае - неверная. Присваивание происходит внутри конструктора.
Моя схема - это всего лишь схема. Она хороша тем, что показывает правильный порядок. На самом деле, если быть точным, то место, где присваивается значение указателю на виртуальную таблицу не может быть указано иначе, чем схематически. То, что указано в статье не совсем верно: присваивание происходит не в самом теле. Автор не учёл, что конструктор может иметь список инициализации и указатель должен стать валидным ещё до того, как начнут инициализироваться поля класса, таким образом присваивание указателя происходит где-то вне конструктора, но после того, как отработал конструктор базового класса. Именно поэтому я использовал схему, а не точный псевдокод.
&quot писал(а):Может я и не прав с порядком
Я рад, что ты умеешь признавать ошибки. Как видишь, я тоже умею.

Re: Вызов виртуальных методов в конструкторах

Добавлено: 27 май 2009, 11:44
Airhand
Romeo
Нет, я уже успокоился :) Я болезненно реагирую лишь в том случае, когда человек, обладающий недостаточными знаниями пытается показать насколько он "крут". Сейчас ты перестал красоваться и я вижу, что стал читать сторонние статьи и анализировать написанное нами, чтобы вести полемику. Также ты пропускаешь те мои ответы, которые бесспорны, беря их себе на заметку. Это меня успокоило и я наоборот хочу тебе помочь.
Я никгда не красовался, а ты прежде чем писать, что это мой код, сначало убедись в этом и не будет таких смешных ситуаций.
Моя схема - это всего лишь схема. Она хороша тем, что показывает правильный порядок. На самом деле, если быть точным, то место, где присваивается значение указателю на виртуальную таблицу не может быть указано иначе, чем схематически. То, что указано в статье не совсем верно: присваивание происходит не в самом теле. Автор не учёл, что конструктор может иметь список инициализации и указатель должен стать валидным ещё до того, как начнут инициализироваться поля класса, таким образом присваивание указателя происходит где-то вне конструктора, но после того, как отработал конструктор базового класса. Именно поэтому я использовал схему, а не точный псевдокод
Пошли отмазки типа "это не я и хата не моя". Она ничем не хороша, т.к. она неверная.

И оставь эти попытки быть психоаналитиком. У тебя фигово получается. Будь лучще тем, на кого учился.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
У Алена Голуба так и не ясно, где инициализуруется табица виртуальных функций. Понятно, что в конструторе/деструкторе механизм виртуальных функий не работает, но где присваивается указатель - неясно.

Re: Вызов виртуальных методов в конструкторах

Добавлено: 27 май 2009, 12:08
BBB
Airhand писал(а):У Алена Голуба так и не ясно, где инициализуруется табица виртуальных функций. Понятно, что в конструторе/деструкторе механизм виртуальных функий не работает, но где присваивается указатель - неясно.
А для Вас Алена Голуб - это единственный и неповторимый авторитет? Т.е. если он что-то о чем-то не упоминает (не важно, либо просто не упоминает, либо не знает этого), то Вы делаете вывод, что это тайна великая есть и никто другой ее уже не в состоянии раскрыть?