注意:这篇文章上次更新于1548天前,文章内容可能已经过时。
This article was last updated1548 days ago, the content may be outdated.
1 |
|
面试官问我这样可以吗?
我犹豫了好久好久… 也不知道可以不可以。
面试官看我答不出来,然后问我知道静态绑定和动态绑定吗?(这是在提示我了)
可我还是不知道可以还是不可以。😥
这道题他问的很含糊,可以还是不可以?这个”可以“该怎么理解,会不会报错?用对象调用成员函数肯定是不会报错的。
他问的可以还是不可以是指这样调用能不能实现多态。也就是说b.print() 的输出是什么?
当时的我只记得多态要看对象类型,对象是 B 类型,所以应该是可以实现多态的吧。
可实际上的结果是:不能实现多态

回来查了一下什么是静态绑定和动态绑定。
查出来的就是八股文式的定义,但是看的多了也多少理解一点。
了解静态绑定和动态绑定之前,要先了解静态类型和动态类型两个概念。
- 静态类型:一个指针(或引用)在程序中被声明的类型,在编译期确定。
- 动态类型:一个指针(或引用)所指对象的实际类型,在运行期确定。
以上两个定义是我的个人理解,未必准确!如有错误,欢迎留言指出。
这两个定义我都说的指针(或引用),因为我查到的大多数博客里都是用正面的例子来说明,他们说 A* p = new B(); p 的静态类型是 A, 动态类型是 B。
但是对于 A b = B();呢?b 还有没有静态类型和动态类型这一说?我觉得这里面 b 是一个栈区对象,而不是指针,没有所谓的动态类型,它只有一个类型,那就是 A 类型,所以 b 对象调用的是 A 类中的 print 函数。
说完了静态类型和动态类型,接下来说静态绑定和动态绑定。
- 静态绑定:又叫早绑定,绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译阶段。
- 动态绑定:又叫晚绑定,绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行阶段。
一般情况下,虚函数是动态绑定的,非虚函数是静态绑定的,函数的默认参数也是静态绑定的。
举几个例子:
1 |
|
最后总结一下实现多态的三个必要条件:
- 需要有继承关系,子类继承父类。
- 子类需要重写父类的虚函数。
- 必须存在向上转型:即父类指针或引用指向子类对象。
其余情况均不能实现多态。


