LINUX.ORG.RU

Как это устроено?

 


0

4

После компиляции вся информация о типах и наследовании в объектном файле исчезает. А вот если объект создается динамически во время выполнения откуда система знает про то какие дестукторы и в какой последовательности надо вызывать? Ведь их нельзя вызывать произвольно а надо в порядке наследования?

И не надо пожалуйста разводить флем на 300 постов как некоторые тут любят делать в попытках показаться умнее чем есть.


И не надо пожалуйста разводить флем на 300 постов как некоторые тут любят делать в попытках показаться умнее чем есть.

А смысл сидеть на форуме, отвечать кому-то, тратить время, как кроме того, чтобы почесать себе чсв?

А вот если объект создается динамически во время выполнения откуда система знает про то какие дестукторы и в какой последовательности надо вызывать?

Там всё превращается в кучу указателей. А код один для всех этих твоих объектов и не создаётся каждый раз после «new». По сути там

void destruct(youStruct s) {
   //alala
   destructParent(s);
   destructParent2(s);
   //etc
}
Посмотри на си, короче.

crutch_master ★★★★★
()

После компиляции вся информация о типах и наследовании в объектном файле исчезает.

Нет. Те кто занимаются Reverse Engineering видят в асме как и обычные наследования, так и вирутальные..

Поиграйся тут:

https://godbolt.org/z/Wl74xV

fsb4000 ★★★★★
()

это говно в /dev модуляторов канешна не интересует

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

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

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

она не знает. ты создаешь объект определенного типа и у него уже на момент компиляции известна таблица виртуальных методов.

Посмотри на реализацию всяких объектных интерфейсов на чистых сях.

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

И цепочка остальных деструкторов вызывается явно из кода деструктора типа.

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

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

Every class with virtual methods (declared/inherited) has its own virtual table(vtable). When a virtual method (any, not just the destructor) is declared virtual, all overrides of that method in derived classes are automatically virtual. The compiler also adds _vptr at the beginning of any such classes having virtual methods. This _vptr will be filled when the class's object is created and will point to the vtable of that class.

will be filled when the class's object is created

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

Вот смотри есть родительский класс dog с методом speak и два потомка dog_a и dog_b.

Как компилятор статически определит указатель в виртуальной таблице на speak если ссылка на dog инициализируется объектом потомка?

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

Очень просто. Таблица виртуальных функций одна на класс, т.е. одна для всех экземпляров. То есть статическая.

anonymous
()
Ответ на: комментарий от Liz812

Как компилятор статически определит указатель в виртуальной таблице на speak если ссылка на dog инициализируется объектом потомка?

При объявлении виртуального метода, создается таблица с указателями на функции-методы. Эта таблица связана с конкретным объектом. Получается, чтобы вызвать метод speak, вызывается функция, на которую указывать первых (например) элемент таблицы виртуальных методов.

Если ты создал объект как new dog, то первый указатель таблицы будет указывать на dog::speak. Если ты создал объект как new dog_a, то первый указатель таблицы будет указывать на dog_a::speak.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Kroz

Я вызываю speak по ссылке на класс dog. Которая в момент исполнения может ссылаться на dog, dog_a или dog_b. Компилятора уже давно нет и про типы никто не знает. Откуда в dog появится правильный указатель на метод speak?

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

В экземпляре класса нет указателя на сам метод. Есть только указатель на таблицу виртуальных функций, в которой этот указатель хранится. Таблица создается при компиляции. При создании экземпляра класса ты указываешь конкретный тип, поэтому vptr указывает на правильную vtbl. В приведенной тобой цитате говорится о заполнении указателя vptr, а не таблицы vtbl, которая заполняется на этапе компиляции.

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

В dog - объекте - есть ссылка на таблицу с виртуальными функциями, которые относятся к его классу. Грубо можно сказать, что эта ссылки и есть идентификатор класса данного объекта (это очень условно).

Ты вызываешь dog->speak, в коде берется объект, берётся из него указатель на таблицу с указателями на методы _vptr (виртуальные функции), и вызывает метод, на который указывал элемент N таблицы. То есть dog->speak превращается в (*(dog->_vptr))[0](self, args) - при условии что у тебя speak - единственная виртуальна функция, так что индекс 0 соответствует именно speak.

Если у тебя в классе есть хоть один виртуальный метод, то компилятор добавляет в класс еще одну переменную - указатель на таблицу виртуальных методов _vptr. То есть даже если у тебя в классе ноль переменных, но есть хотябы одна виртуальная функция, то на самом деле у тебя в класе одна переменная _vptr; ее добавит компилятор.

The compiler also adds _vptr at the beginning of any such classes having virtual methods.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Liz812

Я вызываю speak по ссылке на класс dog.

ссылка на класс dog указывает на конкретный экземпляр класса (dog-a или dog-b), а конкретный экземпляр содержит ссылку на правильный vtable.

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

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

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

И не надо пожалуйста разводить флем на 300 постов как некоторые тут любят делать в попытках показаться умнее чем есть

But you don’t ask with respect. You don’t offer friendship. You don’t even think to call me Godfather

Я за бан. Сама вбрасываешь тупняк, а потом ноешь.

На случай, если ты не знала: от треда можно отписаться.

WitcherGeralt ★★
()

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

На самом деле «знать» не надо. Код (как «клиентский» так и «провайдерский») уже написан и скомпилирован и сделает то, что надо.

Т.е. если класс декларирует деструктор (в заголовочном файле), то код, владеющий обьектом тапкого класса сгенерирует вызов деструктора. Если деструктор виртуальный, то достанет его адрес из vtable и вызовет.

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

KennyMinigun ★★★★★
()
Последнее исправление: KennyMinigun (всего исправлений: 1)
Ответ на: комментарий от WitcherGeralt

Удваиваю этого качка^W паверлифтёра.

anonymous
()
Ответ на: комментарий от xperious

Любитель блондинок, он всегда заходит понудеть.

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

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

Есть такая штука, RTTI.

не надо пожалуйста разводить флем на 300 постов

Вот видишь, как тебя тут любят! Каждый желает высказаться.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Тсссссс, а то она штук тридцать подружек приведет ... /впрочем почему бы и нет?/.

anonymous
()
Ответ на: комментарий от no-such-file

«В момент когда компилятор дошел до этой точки все ссылки должны быть известны, что дает ему возможность заполнить таблицу вызовов правильными указателями, которые уже настроены.» - значит это неправильно? И он вызовы деструкторов строит через RTTI?

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

После компиляции весь исходный код в объектном файле исчезает. Откуда система знает какие функции и в какой последовательности надо вызывать?

// язабан, это цирк с бородатыми девочками

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

А я вот сегодня в парикмахерской бороду подстриг /сантимера полтора, а была сантиметров 15. Старит сильно .../.
Как обычно мне говорят - «Вы лет десять сбросили» /не возражал бы и двадцать/.
Если кто спросит зачем мне борода, то не смогу ответить /и не потому, что скрываю/.
Для меня этот вопрос равносилен - «А зачем вы дышите?».

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

Начальнику сказал так - «У подчиненного борода должна быть не больше, чем у начальника».

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

Привычка, стеснительность, причины могут быть разные. А вообще сейчас любой чмо 20 летнее с бородищей ходит. Типа показать брутальность, хотя глаза щенячьи.

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

Это если у бороды нет VMT. Тогда и красивая, и не старит, и все деструкторы в правильном месте.

anonymous
()

Информация о типах есть во время компиляции. Этого достаточно, чтобы сгенерировать код деструкторов.

А вообще кончай троллить тупняком.

ox55ff ★★★★★
()

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

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

Что ты имеешь против девочек?

Воу, воу, господа, давайте не будем доставать, что имеем, и размахивать. Здесь могут быть дети.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от anonymous

огда и красивая, и не старит, и все деструкторы в правильном месте.

Эээ борода здесь не причем, здесь доминирует «кривизна рук».

anonymous
()
Ответ на: комментарий от Liz812

Возможно эти две классные статьи дадут тебе ответы [1] [2]

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

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

Эээ борода здесь не причем, здесь доминирует «кривизна рук».

«Гусарам молчать»!

Однако господа офицеры у многих руки растут откуда?
Из ж...ы.
И деструкторы у них такие же.
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.