2015-10-07 3 views
0

Я пытаюсь имитировать концепцию vptr/vtable. У меня есть 3 вопроса, касающиеся следующих:Виртуальный указатель таблицы и моделирование виртуальной таблицы

1. Я не определили конструктор для класса FOO, который должен быть хорошо, как можно увидеть внутри основной (Foo *ptr= new FOO ОК). Но когда я создаю объект в куче для того же самого внутри FooVtable :: bar(), он жалуется на отсутствие соответствующего конструктора по умолчанию. Зачем?

2. я вижу, что точки vptr в какой-то адрес (даже если нет new FooVTable сделано для vptr, я думаю, к т е р по умолчанию это делает. Это ожидается?), FooVtable::bar становится званых, но соиЬ оленья кожа напечатать заявление. Зачем?

3. Внутри callsomeFun(), я звоню foo->vptr->bar. Что я пытаюсь достичь здесь в том, что vptr->bar часть foo->vptr-> Бар должен фактически назвать указатель на функцию-член Foo :: бар(), который я предполагаю разве непосредственно возможно, следовательно, Я объявил void bar(Foo* foo), внутри которого я собираюсь позвонить Foo:bar через ptr. Я подхожу к нему правильно, или есть лучший способ приблизиться к этому?

class Foo; 
struct FooVtable { 
    void bar(Foo* foo) 
    { 
     //Foo *ptr = new Foo; //Why does this throw error as No Default constructor? 
     cout<"FooVTable : bar"; //Doesnt get printed even though gets called 
    } 
}; 
struct Foo { 
    FooVtable* vptr; 
    void bar(Foo *foo) 
    { 
     cout<<"Foo : bar"; 
    } 
}; 

int callSomeFun(Foo* foo) { 
    foo->vptr->bar(foo); 
    return 0; 
} 
int main() 
{ 
    Foo *ptr=new Foo; 
    callSomeFun(ptr); 
    return 0; 
} 
+0

Настоящая версия vtable не содержит фактических функций, а указывает на функции. И эти функции возьмут указатель 'this *' как первый параметр. –

ответ

1
  1. when i create the object on heap for the same inside FooVtable::bar() , it complains about no appropriate default constructor found. Why?

Это плохое сообщение об ошибке в ситуации, когда вы пытаетесь использовать класс, прежде чем он был полностью объявлен. В другом компиляторе сообщение может больше напоминать «ошибка: недопустимое использование неполного типа» класса Foo ».

Один из способов решить эту проблему было бы поставить полный struct Foo материал выше FooVtable, а затем использовать вперед декларацию FooVtable вместо Foo.

  1. I see that vptr points to some address(even though there is no new FooVTable done for vptr,i guess ctor by default does it. is it expected?), FooVtable::bar is getting called but cout doesnt print the statement. Why?

Это vptr неинициализирован. Примитивные типы, такие как указатели, не инициализируются каким-либо значением по умолчанию только new. Так что там, где есть мусор. Этого ожидает многое.

Что бы ни случилось после вызова функции с помощью указателя с размером мусора, это неопределенное поведение. Так что все могло случиться, и не было бы гарантированного объяснения.

Однако в этом случае возникает и другая проблема: вы сделали опечатку. cout<"FooVTable : bar"; имеет один < и таким образом будет делать странное и бесполезное сравнение вместо вывода чего-либо.

  1. foo->vptr->bar should actually call a pointer to member function Foo::bar() , which i guess isnt directly possible

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

Am i approaching it right, or is there a better way to approach this?

Это действительно зависит от того, насколько реальной реализации вы пытаетесь «имитировать» и что вы надеетесь достичь этим.

Смежные вопросы