Подтвердить что ты не робот

Является ли С++ стандартом запрещать хранение функций-членов внутри отдельных экземпляров класса?

В реализациях С++ обычно код не сохраняется (в любой форме) внутри экземпляров класса. Сегмент кода не находится в том же пространстве памяти, что и объекты и тому подобное. Это означает, что функции-члены не "хранятся" внутри экземпляров класса.

Но когда был задан вопрос об этом, мне стало интересно: в какой степени, если вообще, стандарт запрещает функции-члены храниться внутри их инкапсуляции класс, насколько экземпляр класса создает копию этих функций? Теоретически, могу ли я сделать реализацию, которая работала таким образом? И может ли он даже отдаленно соблюдать обычные ABI?

4b9b3361

Ответ 1

Если в С++ код был первоклассным значением, тогда код для функции-члена был бы просто членом класса const static, и вы больше не ожидали бы найти это в экземпляре, чем любой другой статический член данных. (& section; 9.4.2: "Статический член данных не является частью подобъектов класса." )

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

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

Но существует исключение для типов стандартного макета, который является подмножеством классов без виртуальных функций-членов, выраженных в & sect; 9.12/18, что требует, чтобы два типа стандартных макетов с одинаковыми исходными элементами имели одинаковый макет для исходных элементов. Напоминая, что объекты стандартного макета должны быть просто скопированы с помощью memcpy (& sect; 3.9/3), должны быть смежными в памяти (& sect; 1.8/5) и должны включать их членов в порядок (& sect; 9.12/13), это требование делает невозможным включение статических данных, специфичных для класса, в любой объект стандартного макета, который будет включать код для функций-членов.

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