|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Присвоение функции значения |
|
C/C++ - Присвоение функции значения
|
Ветеран Сообщения: 1404 |
Профиль | Отправить PM | Цитировать
|
|
Отправлено: 10:04, 06-11-2008 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Цитата mrcnn:
Цитата mrcnn:
|
||
Отправлено: 12:14, 06-11-2008 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 1404
|
Профиль | Отправить PM | Цитировать Это не реальный код, а теоретический. Все имена - теоретические. Первой строкой я хотел показать, что это указатель на класс E и ничего больше. Надо было добавить многоточия? Предполагалось, что он уже инициализирован нормальным адресом класса при обращении к нему во второй строке.
Затем производится обращение к чистой виртуальной функции. Я не совсем понимаю механизм, по которому будет вызвана функция, стоящая за этим L, но функция, которая будет вызвана, определена, где-то в другом месте. Переопределять L в этом классе вообще нельзя. Надо переопределять то, что стоит за этим L. Но как допустим найти, какая именно? Я не понимаю взаимосвязи между вот этой чисто виртуальной функцией, и той функцией, которая будет вызвана при обращении к ней, т.е. p->L. Класс E не является наследником других классов, но у него есть наследники. В реальном рабочем коде примерно следующее. |
------- Последний раз редактировалось mrcnn, 06-11-2008 в 17:10. Отправлено: 16:37, 06-11-2008 | #3 |
Новый участник Сообщения: 49
|
Профиль | Отправить PM | Цитировать Цитата mrcnn:
p->L это E::L |
|
Отправлено: 03:44, 07-11-2008 | #4 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Обрисую как это устроено. Любой полиморфный класс (то есть содержащий виртуальные функции) содержит внутреннюю переменную - указатель на таблицу виртуальных функций.
class E { private: virtual void mem_fun() { // do something } public: virtual bool L(int) { // do something } } // кодируется как (условный код): struct E_vtbl { int base_offset = 0; mem_fun_address = &mem_fun; // адрес кода mem_fun L_address = &L; // адрес кода L } struct E_class { E_vtbl* _vtbl = &E_vtbl; } // таким образом вызов виртуальной функции идёт так: // p->mem_fun(); (*p->_vtbl->mem_fun_address)(p + p->_vtbl->base_offset); // p->L(1); (*p->_vtbl->L_address)(p + p->_vtbl->base_offset, 1); class E { int a; public: virtual bool L(int) = 0; } class E1 : public E { int b; public: virtual bool L(int) { cout << "E1::L\n"; } } class E2 : public E { double c; public: virtual bool L(int) { cout << "E2::L\n"; } } // кодируется как: struct E1_vtbl { base_offset = 0; L_address = &E1::L // E_vtbl, заполненная правильным адресом E1::L } struct E1_vtbl_E { base_offset = -4; L_address = &E1::L // E_vtbl, заполненная правильным адресом E1::L } struct E2_vtbl { base_offset = 0; L_address = &E2::L // E_vtbl, заполненная правильным адресом E2::L } struct E2_vtbl_E { base_offset = -4; L_address = &E2::L // E_vtbl, заполненная правильным адресом E2::L } struct E1_class { // общие для всех E1_vtbl* _vtbl = &E1_vtbl; // таблица E1 // составляющий класс E E_vtbl* _vtbl1 = &E1_vtbl_E; // таблица E int a; // данные E int b; // общие данные } struct E2_class { // общие для всех E2_vtbl* _vtbl = &E2_vtbl; // таблица E2 // составляющий класс E E_vtbl* _vtbl1 = &E2_vtbl_E; // таблица E int a; // данные E double c; // общие данные } 2. вызов E::L - из виртуальной таблицы (*E_ptr->_vtbl->L)(E_ptr+E_ptr->_vtbl->base_offset, 1). В результате, если посчитать, вызов преобразуется в E2_ptr->E::L2 Для чего нужен base_offset? Дело в том, что в C++ классы обладают множественным виртуальным наследием. Чтобы программа могла при реализации вызова могла преобразовать адрес к наследнику от любого базового класса (который может и не "знать", в состав чего входит). Иногда base_offset вводят в тело функции. Идёт вызов кода, который вносит изменения в указатель this и делает прыжок на функцию класса-наследника |
|
Отправлено: 08:26, 07-11-2008 | #5 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Разное - WLAN, присвоение адреса, шарик в иконке, в трее бегает, хотя уже подключён | _ib_ | Microsoft Windows 2000/XP | 5 | 16-09-2009 16:26 | |
Присвоение прав на системные файлы и папки. Удаление скрытого администратора. | D@n1k007 | Автоматическая установка Windows 11 / 10 / 8 / 7 / Vista | 10 | 27-10-2008 04:46 | |
XP. Присвоение IP сетевому интерфейсу | Stesh | Хочу все знать | 2 | 02-10-2006 18:43 | |
Значения параметров | h00ligan | Автоматическая установка Windows 2000/XP/2003 | 1 | 21-06-2005 12:23 | |
Значения абривеатур | Trojn | Хочу все знать | 11 | 21-05-2003 23:58 |
|