面试问到多态的问题,我是这样回答的:
多态分为编译时多态和运行时多态。
编译时多态就是函数重载来实现的。
运行时多态是用虚函数来实现。
主要是子类重写父类的虚函数,使用父类引用或者父类指针来调用。
对象首地址是有一个指向虚函数表的指针的。
虚函数表存储虚函数的地址。
汇编的时候直接调用虚函数表中对应的函数。
Base_L* b = new Son();
b->mm();
或者
Son son;
Base_L& refBase = son;
refBase.mm();
面试官问题
然后他问我,父类有一个虚函数,子类继承父类,子类有没有虚函数表。我迟疑了。
支支吾吾半天说不出来。子类是有父类的虚函数表指针的。子类是有父类的整个数据的
子类对象内存中本来就存在父类的一个实例,当然包含父类的所有东西。
子类继承父类,重写父类虚函数,那么子类对象中有几个虚函数表指针?
2个 一个是子类的,一个是父类的。
子类继承父类,那么子类对象中有几个虚函数表指针?
1个 那个是父类的。
虚析构是怎么回事
class object
{
public:
object() { value = 10; }
virtual void speak() { cout << "object::speak" << endl; }
virtual ~object()
{
cout << "object::~object" << endl;
}
private:
int value;
};
class SonObject :public object
{
public:
SonObject() {}
~SonObject()
{
cout << "SonObject::~SonObject" << endl;
}
virtual void speak() { cout << "SonObject::speak" << endl; }
private:
};
int main()
{
object* o = new SonObject();
o->speak();
delete o;
return 0;
}
如果不写,delete p; 的时候只会调用父类析构函数,派生类对象的空间没有释放掉。
基类声明虚析构函数,其实子类也有析构函数,我理解子类相当于把虚析构函数重写了,来支持多态。先调用子类析构函数,再调用父类析构函数。