C++在面向对象编程中,存在着静态绑定和动态绑定的定义,本节即是主要讲述这两点区分。
  我是在一个类的继承体系中分析的,因此下面所说的对象一般是指一个类的实例。
  首先我们需要明确几个名词定义:
  静态类型:对象在声明时采用的类型,在编译期既已确定;
  动态类型:通常是指一个指针或引用目前所指对象的类型,是在运行期决定的;
  静态绑定:绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译期;
  动态绑定:绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行期;
  从上面的定义也可以看出,非虚函数一般都是静态绑定,而虚函数都是动态绑定(如此才可实现多态性)。
  先看代码和运行结果:
1 class A
2 {
3 public:
4     /*virtual*/ void func(){ std::cout << "A::func() "; }
5 };
6 class B : public A
7 {
8 public:
9     void func(){ std::cout << "B::func() "; }
10 };
11 class C : public A
12 {
13 public:
14     void func(){ std::cout << "C::func() "; }
15 };
  下面逐步分析测试代码及结果,
  1 C* pc = new C(); //pc的静态类型是它声明的类型C*,动态类型也是C*;
  2 B* pb = new B(); //pb的静态类型和动态类型也都是B*;
  3 A* pa = pc;      //pa的静态类型是它声明的类型A*,动态类型是pa所指向的对象pc的类型C*;
  4 pa = pb;         //pa的动态类型可以更改,现在它的动态类型是B*,但其静态类型仍是声明时候的A*;
  5 C *pnull = NULL; //pnull的静态类型是它声明的类型C*,没有动态类型,因为它指向了NULL;
  如果明白上面代码的意思,请继续,
  1 pa->func();      //A::func() pa的静态类型永远都是A*,不管其指向的是哪个子类,都是直接调用A::func();
  2 pc->func();      //C::func() pc的动、静态类型都是C*,因此调用C::func();
  3 pnull->func();   //C::func() 不用奇怪为什么空指针也可以调用函数,因为这在编译期确定了,和指针空不空没关系;