* C++多态分为编译时多态和运行时多态.
* 编译时多态通过函数或操作符的重载来实现, 见例1.
* 运行时多态通过虚函数(包括纯虚函数)来实现, 见例2.
* 关键字virtual可用于function declaration或class declaration.
* 关键字virtual修饰函数时声明虚函数.
* 关键字virtual修饰类时声明虚基类(virtual base class). 虚基类的作用是节省空间, 避免重复和二义性, 和多态没有关系.
* 抽象类(abstract class) = 含有纯虚函数(pure virtual function)的类(不管是自己声明的还是继承的), 见例6.
1. 对普通成员函数的调用由指针/引用的类型决定(编译时多态)
#include
using namespace std;
class B{
public: void vf()
{ cout << "This is class B" << endl; }
};
class D: public B
{
public: void vf()
{ cout << "This is class D" << endl; }
};
main()
{ B b, *pb;
D d, *pd;
pb = &b;
pb->vf();
pb = &d;
pb->vf(); // no cast needed
pd = (D*)&b;
pd->vf(); // must cast explicitly
pd = &d;
pd->vf();
}This is class BThis is class BThis is class DThis is class
D2. 对虚函数的调用由指针/引用的赋值决定(运行时多态)
#include
using namespace std;
class B{
public: void virtual vf()
{ cout << "This is class B" << endl; }
};
class D: public B
{
public: void vf()
{ cout << "This is class D" << endl; }
};
main()
{
B b, *pb;
D d, *pd;
pb = &b;
pb->vf();
pb = &d;
pb->vf();
pd = (D*)&b;
pd->vf();
pd = &d;
pd->vf();
}
This is class BThis is class DThis is class BThis is class D3. 普通成员函数如果不被调用则可以不定义函数内容
#include
using namespace std;
class B{ // non-virtual function may be undefined as long as it's not called
public: void vf();
};
class D: public B
{
public: void vf()
{ cout << "This is class D" << endl; }
};
main()
{
B b, *pb;
D d, *pd;
pd = (D*)&b;
pd->vf();
pd = &d;
pd->vf();
}
This is class DThis is class D4. 基类虚函数必须定义内容或是纯虚函数(否则该基类和其所有派生类都不能实例化)
#include
using namespace std;
class B{
public: void virtual vf();
};
class D: public B
{
public: void vf()
{ cout << "This is class D" << endl; }
};
main()
{ D d, *pd;}
5. 派生类虚函数如果该派生类不实例化(当然也就没啥用处)则可以不定义内容
#include
using namespace std;
class B
{
public: void virtual vf()
{ cout << "This is class B" << endl; }
};
class D: public B
{
public: void vf();
};
main()
{ B b, *pb;
D *pd;
// instantiation like "D d;" or "D *pd = new D;" causes link error
pb = &b;
pb->vf();
pd = (D*)&b;
pd->vf();
}
This is class BThis is class B6. 纯虚函数没有定义(一旦实现就不再是纯虚函数)
#include
using namespace std;
// B is abstract class because its vf() is pure virtual function
class B
{ public: void virtual vf()=0;};
// C is also abstract class because it inherits pure virtual function vf()
class C: public B
{ // "public: void vf();" here would change vf() to be non-pure virtual
// function and cause link error when D instantiates
// but if D derives from B directly as "class D: public B" then it is OK
};
// D is not abstract class because its vf() is defined and no longer pure virtual function
class D: public C
{ public: void vf()
{ cout << "This is class D" << endl; }
};
// E is not abstract class and has another implementation of vf()
class E: public D
{ public: void vf()
{ cout << "This is class E" << endl; }
};
main()
{ B *pb;
// instantiation like "B b;" or "B *pb = new B;" causes link error
C *pc;
// instantiation like "C c;" or "C *pc = new C;" causes link error
D d, *pd;
E e, *pe;
pb = &d;
pb->vf();
pc = &e;
pc->vf();
pd = &e;
pd->vf();
pe = (E*)&d;
pe->vf();
}
This is class DThis is class EThis is class EThis is class D3+4+5+6总结起来就是: 对所有的函数, 不定义=>不能调用; 对纯虚函数: 不定义=>该类不能实例化; 对非纯的虚函数: 不定义=>该类及其派生类都不能实例化
1.使用由派生类初始化的基类的指针访问类的成员函数
2。 访问的类中的函数为虚函数
这样就能实现多态,便于程序的扩展