Путаница из-за виртуального стола

мне задали этот вопрос в интервью. Сколько виртуальных таблиц создает следующая программа и каков выход в каждом случае.

#include <iostream>
using namespace std;
class A
{
virtual void func1()
{
cout << "0 " <<endl;
}

virtual void func2()
{
cout << "1 " <<endl;
}
};

class B:Public A
{
void func1()
{
cout << "2" <<endl;
}
};

class C:public B
{
virtual void func2()
{
cout << "3" <<endl;
}
}

int main()
{
A* objA;

B objB ;
C objC ;

//case1:
objA = &objB;
objA->func1();
//case2:
objA = &objC;
objA->func2();
objA->func1();
return 0;
}

я запутался в классе B. Создает ли он vtable для класса B? какая функция будет вызвана в этом случае. может кто-нибудь объяснить мне.

1

Решение

Смотрите комментарии

// I'll pretend you have a #include <stdio.h> here

class A
{
virtual void func1()
{
print 0; // error!!  I'll pretend this was puts("0");
}

virtual void func2()
{
print1;  // error!!  I'll pretend this was puts("1");
}
};

// there is a virtual table for class A. (for two virtual methods)class B:Public A
{
void func1()
{
print2; // error!!  I'll pretend this was puts("2");
}
};

// there is a virtual table for class B. (for two virtual methods)class C:public B
{
virtual void func2()
{
print 3; // error!!  I'll pretend this was puts("3");
}
}

// there is a virtual table for class C. (for two virtual methods)int main()
{
A objA;
B* objB = new B();

C* objC = new C();

//case1:
objA = &objB;   // error!! left side of type A right side of type B**
objA->func1();  // error!!  operator -> on non pointer

//case2:
objA = &objC;  // error!! left side of type A right side of type B**
objA->func2(); // error!!  operator -> on non pointer
objA->func1(); // error!!  operator -> on non pointer
return 0;
}

// nothing is printed

Поскольку вы отредактировали OP-код, здесь он является ответом для новой версии вашего кода. Смотрите комментарии:

#include <iostream>
using namespace std;
class A
{
virtual void func1()
{
cout << "0 " <<endl; // it's ok, but is the space supposed to be there?
}

virtual void func2()
{
cout << "1 " <<endl; // it's ok, but is the space supposed to be there?
}
};
// there is a virtual table for class A. (for two virtual methods)

class B:Public A  // error!! I'll pretend Public was public (lowercase)
{
void func1()
{
cout << "2" <<endl; // it's ok, but here there's no space, is that correct?
}
};
// there is a virtual table for class B. (for two virtual methods)

class C:public B
{
virtual void func2()
{
cout << "3" <<endl; // it's ok, but here there's no space, is that correct?
}
}
// there is a virtual table for class C. (for two virtual methods)

int main()
{
A* objA;

B objB ;
C objC ;

//case1:
objA = &objB;
objA->func1(); // outputs (to stdout) a '2' (two) and whatever a
// newline is on your system (could be '\r' or '\n' or both
// or in fact anything your platform defines a newline is)
// stdout is then flushed.
//case2:
objA = &objC;
objA->func2(); // outputs (to stdout) a '3' (three) and whatever a
// newline is on your system (could be '\r' or '\n' or both
// or in fact anything your platform defines a newline is)
// stdout is then flushed.

objA->func1(); // outputs (to stdout) a '2' (two) and whatever a
// newline is on your system (could be '\r' or '\n' or both
// or in fact anything your platform defines a newline is)
// stdout is then flushed.
return 0;
}
// the output is '2' <newline> '3' <newline> '2' <newline>
// where the actual character(s) for <newline> are platform dependent
1

Другие решения

Экземпляры класса B также являются экземплярами типа A. Ваш класс B вызывает конструктор для класса A, и если B не переопределяет func1 () из A, тогда B имеет виртуальный func2 () и переопределение для func1 () из A.

0

По вопросам рекламы [email protected]