Chinaunix首页 | 论坛 | 博客
  • 博客访问: 644216
  • 博文数量: 227
  • 博客积分: 8017
  • 博客等级: 中将
  • 技术积分: 2069
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-08 22:50
文章分类

全部博文(227)

文章存档

2011年(10)

2010年(55)

2009年(28)

2008年(134)

我的朋友

分类: C/C++

2008-10-08 20:06:12

/*最近项目中要用到C++的多态,感觉这篇文章分析的很好。转载如下: */

* 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 B
This is class B
This is class D
This is class D
2. 对虚函数的调用由指针/引用的赋值决定(运行时多态)
#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 B
This is class D
This is class B
This is class D
3. 普通成员函数如果不被调用则可以不定义函数内容
#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 D
This is class D
4. 基类虚函数必须定义内容或是纯虚函数(否则该基类和其所有派生类都不能实例化)
#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:
unresolved external symbol "public: virtual void __thiscall B::vf(void)" (?vf@B@@UAEXXZ)
5. 派生类虚函数如果该派生类不实例化(当然也就没啥用处)则可以不定义内容
#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 B
This is class B
6. 纯虚函数没有定义(一旦实现就不再是纯虚函数)
#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 D
This is class E
This is class E
This is class D
3+4+5+6总结起来就是: 对所有的函数, 不定义=>不能调用; 对纯虚函数: 不定义=>该类不能实例化; 对非纯的虚函数: 不定义=>该类及其派生类都不能实例化.
阅读(783) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~