你必须非常努力,才能看起来毫不费力!
分类: C/C++
2008-10-13 21:35:06
* 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 B2. 对虚函数的调用由指针/引用的赋值决定(运行时多态)
This is class B
This is class D
This is class D
#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 B3. 普通成员函数如果不被调用则可以不定义函数内容
This is class D
This is class B
This is class D
#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 D4. 基类虚函数必须定义内容或是纯虚函数(否则该基类和其所有派生类都不能实例化)
This is class D
#include
using namespace std;
class B
{
// virtual function in base class must be defined or be pure
// unless the base class and all its derived classes are not instantiated
public: void virtual vf();
};
class D: public B
{
public: void vf() { cout << "This is class D" << endl; }
};
main()
{
D d, *pd;
}
error LNK2001:5. 派生类虚函数如果该派生类不实例化(当然也就没啥用处)则可以不定义内容
unresolved external symbol "public: virtual void __thiscall B::vf(void)" (?vf@B@@UAEXXZ)
#include
using namespace std;
class B
{
public: void virtual vf() { cout << "This is class B" << endl; }
};
class D: public B
{
// virtual function in derived class may be undefined as long as
// the derived class is not instantiated
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 B6. 纯虚函数没有定义(一旦实现就不再是纯虚函数)
This is class B
#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 D3+4+5+6总结起来就是: 对所有的函数, 不定义=>不能调用; 对纯虚函数: 不定义=>该类不能实例化; 对非纯的虚函数: 不定义=>该类及其派生类都不能实例化.
This is class E
This is class E
This is class D