Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - [решено] Виртуальные функции(vtable)

Ответить
Настройки темы
C/C++ - [решено] Виртуальные функции(vtable)

Аватара для crashtuak

Старожил


Сообщения: 467
Благодарности: 25


Конфигурация

Профиль | Отправить PM | Цитировать


Добрый день. Вот разбираюсь с виртуальными функциями. На сколько я понял, в начале класса, в котором есть виртуальные методы, делается указатель на таблицу(vtable), в которой хранятся указатели на функции конкретного класса. Теперь вопрос - если класс наследуется от двух других классов с виртуальными методами, то в нем будут хранится две таблицы(по 1 на каждого виртуального предка)? И что бы кастануть наш класс к любому из предков, надо юзать dynamic_cast<>?

-------
Мне надо не так много "Полезных сообщений", чтоб сровнять их количество с моими постами :).


Отправлено: 22:45, 16-08-2013

 
pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Про то, как обычно оно устроено (советую прочитать все лекции - это перевернёт и упорядочит твой мир):
http://www.stanford.edu/class/archiv...2/Slides12.pdf
Про то, для чего и что может dynamic_cast (имхо лучше им не злоупотреблять):
http://msdn.microsoft.com/en-us/library/cby9kycs.aspx

Как правило любой dynamic_cast начинается с прыжка в базовый класс, а дальше поиск кандидата по всем дочерним классам.
Это сообщение посчитали полезным следующие участники:

Отправлено: 08:41, 17-08-2013 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Аватара для crashtuak

Старожил


Сообщения: 467
Благодарности: 25

Профиль | Отправить PM | Цитировать


pva, спасибо, чтиво интереснейшее. Сам я работаю на Java, и для меня привычно, когда абсолютно все что можно, скрыто за интерфейсами, и простым кастом можно привести объект наследника к одному из нескольких интерфейсов. А в с++, как оказалось, не все так просто. Вот что получилось у меня:
Код: Выделить весь код
class i1
{
  virtual m1() = 0;
};
class i2
{
  virtual m2() = 0;
};
class impl : public i1, public m2
{
  //implementation of i1,i2
}
//main
impl* implInst = new impl();
i2* i2Cast = (i2*)implInst;
И каково было мое удивление, когда вызывался m1() . Как оказалось, компилятор под видом i2 принял i1(который в impl первый в памяти), обратился к i1_vtable, и вызвал m1(). И, кстати, при передаче наследника в методы вида void doSomething(i2*) генерируется код, идентичный для dynamic_cast<>, так что, скорее всего, избежать dynamic_cast<> не выйдет. Для примера
Код: Выделить весь код
	Action* v = dynamic_cast<Action*>(с);
00E93BEF  cmp         dword ptr [ff],0  
00E93BF3  je          wmain+143h (0E93C03h)  
00E93BF5  mov         eax,dword ptr [ff]  
00E93BF8  add         eax,4  
00E93BFB  mov         dword ptr [ebp-130h],eax  
00E93C01  jmp         wmain+14Dh (0E93C0Dh)  
00E93C03  mov         dword ptr [ebp-130h],0  
00E93C0D  mov         ecx,dword ptr [ebp-130h]  
00E93C13  mov         dword ptr [v],ecx  
	doAction(ff);
00E93C16  cmp         dword ptr [ff],0  
00E93C1A  je          wmain+16Ah (0E93C2Ah)  
00E93C1C  mov         eax,dword ptr [ff]  
00E93C1F  add         eax,4  
00E93C22  mov         dword ptr [ebp-130h],eax  
00E93C28  jmp         wmain+174h (0E93C34h)  
00E93C2A  mov         dword ptr [ebp-130h],0  
00E93C34  mov         ecx,dword ptr [ebp-130h]  
00E93C3A  push        ecx  
00E93C3B  call        doAction (0E91226h)  
00E93C40  add         esp,4
где ff реализует Action, возможно, что то поменялось бы с оптимизациями(код дебажный), но я не думаю, что одинаковый код можно по разному оптимизировать .
UPD: хотя, скорее всего, в других ситуациях dynamic_cast выдаст более навороченый код, чем в данном случае.

-------
Мне надо не так много "Полезных сообщений", чтоб сровнять их количество с моими постами :).


Последний раз редактировалось crashtuak, 17-08-2013 в 17:20.


Отправлено: 17:13, 17-08-2013 | #3

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Демонстрация static_cast, dynamic_cast
Код: Выделить весь код
class i1 {
public:
	virtual void foo() = 0;
};

class i2 {
public:
	virtual void bar() = 0;
};

class i3 {
public:
	virtual void goo() = 0;
};

class i4 {
public:
 	virtual void poo() = 0;
};

class impl: public i3, public i1, public i2 {
public:
	void goo() { cout << "goo()" << endl; }
	void foo() { cout << "foo()" << endl; }
	void bar() { cout << "bar()" << endl; }
};

int main() {
	impl *impl_ = new impl();
	i1 *i1_ = impl_;
 	i2 *i2_ = impl_;
	i3 *i3_ = impl_;
	i1 *side_cast = dynamic_cast<i1*>(i2_); // статически не наследуются
	i4 *bad_cast = dynamic_cast<i4*>(i2_); // статически не наследуются

	i1_->foo();
	i2_->bar();
	side_cast->foo();

	cout << "impl=" << impl_ << endl;
	cout << "i1=" << i1_ << endl;
	cout << "i2=" << i2_ << endl;
	cout << "i3=" << i3_ << endl;
	cout << "side_cast=" << side_cast << endl;
	cout << "bad_cast=" << bad_cast << endl;

	return 0;
}
Код: Выделить весь код
foo()
bar()
foo()
impl=0x3e1030
i1=0x3e1034
i2=0x3e1038
i3=0x3e1030
side_cast=0x3e1034
bad_cast=0
Это сообщение посчитали полезным следующие участники:

Отправлено: 00:24, 18-08-2013 | #4



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - [решено] Виртуальные функции(vtable)

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
C/C++ - Множественное наследование, виртуальные функции Alexanderkrup Программирование и базы данных 2 15-12-2011 05:28
Система - Виртуальные машины. ALEKCEN Программное обеспечение Windows 8 16-12-2009 15:47
Прочие - виртуальные диски tt-rtv Программное обеспечение Windows 0 04-03-2009 13:03
Виртуальные хосты C+C Вебмастеру 10 18-11-2008 15:10
Виртуальные машины Guest Хочу все знать 37 15-10-2007 03:22




 
Переход