C++ 的虚函数主要就是 实现多态机制,主要是通过一个虚函数表,知道具体的子类函数还是父类函数的地址,在执行。
先来看一个父类:
父类的虚函数表:
表中的最后一段区域 . 表示虚函数表的结束标志,若此处为1 还有下一个虚表 为0 虚表结束。
一般继承(没有覆盖的情况)
没有覆盖的情况下继承,子类的虚函数地址 存放在父类的后面:
继承(存在覆盖):多态
此时的虚函数表:
可以看到子类覆盖父类的函数f();
所以当 Base * p = new Derived;
p->f();
在此虚函数表中,调用的就是子类的f()函数;
但当使用p->g1()的时候 出现编译错误,父类指针不能指向子类的其他非覆盖的成员函数。
虚继承:
主要就是为了解决多继承的问题;
简述代码:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f()
{
cout << "f() == " <<endl;
}
virtual void g()
{
cout << "g() == " <<endl;
}
virtual void h()
{
cout << "h() == " <<endl;
}
};
class Derived:public Base
{
public:
void f0()
{
cout << "Derived() - f() == " << endl;
}
void g0()
{
cout << "Derived() - g() == " << endl;
}
};
class Derived1:public Base
{
public:
void f1()
{
cout << "Derived() - f() == " << endl;
}
void g1()
{
cout << "Derived() - g() == " << endl;
}
};
class Derived2:public Derived,public Derived1
{
public:
void P()
{
cout << "Derived2 - P() == " << endl;
}
};
int main()
{
//Base *b = new Derived;
//b->f();
//子类 调用自己的成员函数 不能使用->
//b->g1(); 编译错误 使用父类指针不能指向子类的成员函数
Derived2 ddd;
ddd.f();
return 0;
}
不是虚继承,
会出现错误:
原因:不清楚f()到底所属谁;
应加上虚继承:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f()
{
cout << "f() == " <<endl;
}
virtual void g()
{
cout << "g() == " <<endl;
}
virtual void h()
{
cout << "h() == " <<endl;
}
};
class Derived:virtual public Base
{
public:
void f0()
{
cout << "Derived() - f() == " << endl;
}
void g0()
{
cout << "Derived() - g() == " << endl;
}
};
class Derived1:virtual public Base
{
public:
void f1()
{
cout << "Derived() - f() == " << endl;
}
void g1()
{
cout << "Derived() - g() == " << endl;
}
};
class Derived2:public Derived,public Derived1
{
public:
void P()
{
cout << "Derived2 - P() == " << endl;
}
};
int main()
{
//Base *b = new Derived;
//b->f();
//子类 调用自己的成员函数 不能使用->
//b->g1(); 编译错误 使用父类指针不能指向子类的成员函数
Derived2 ddd;
ddd.f();
return 0;
}
运行正确;