您的位置:首页 > 编程语言 > C语言/C++

c++多态详解 实例

2014-11-03 16:25 435 查看
C++多态分为编译时多态和运行时多态.

* 编译时多态通过函数或操作符的重载来实现, 见例1.

* 运行时多态通过虚函数(包括纯虚函数)来实现, 见例2.

* 关键字virtual可用于function declaration或class declaration.

* 关键字virtual修饰函数时声明虚函数.

* 关键字virtual修饰类时声明虚基类(virtual base class). 虚基类的作用是节省空间, 避免重复和二义性, 和多态没有关系.

* 抽象类(abstract class) = 含有纯虚函数(pure virtual function)的类(不管是自己声明的还是继承的), 见例6.

1. 对普通成员函数的调用由指针/引用的类型决定(编译时多态)
#include <iostream>
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 <iostream>
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 <iostream>
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 <iostream>
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 <iostream>
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 <iostream>
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总结起来就是: 对所有的函数, 不定义=>不能调用; 对纯虚函数: 不定义=>该类不能实例化; 对非纯的虚函数: 不定义=>该类及其派生类都不能实例化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: