注意:这篇文章上次更新于1568天前,文章内容可能已经过时。
This article was last updated1568 days ago, the content may be outdated.
1 |
|
面试官问我这样可以吗?
我犹豫了好久好久… 也不知道可以不可以。
面试官看我答不出来,然后问我知道静态绑定和动态绑定吗?(这是在提示我了)
可我还是不知道可以还是不可以。😥
The interviewer asked me: can this be done?
I hesitated for a long, long time… and still didn’t know whether it could or couldn’t.
Seeing that I couldn’t answer, the interviewer then asked whether I knew about static binding and dynamic binding. (That was a hint to me.)
But I still didn’t know whether it could or couldn’t. 😥
这道题他问的很含糊,可以还是不可以?这个”可以“该怎么理解,会不会报错?用对象调用成员函数肯定是不会报错的。
他问的可以还是不可以是指这样调用能不能实现多态。也就是说b.print() 的输出是什么?
当时的我只记得多态要看对象类型,对象是 B 类型,所以应该是可以实现多态的吧。
可实际上的结果是:不能实现多态

回来查了一下什么是静态绑定和动态绑定。
查出来的就是八股文式的定义,但是看的多了也多少理解一点。
了解静态绑定和动态绑定之前,要先了解静态类型和动态类型两个概念。
- 静态类型:一个指针(或引用)在程序中被声明的类型,在编译期确定。
- 动态类型:一个指针(或引用)所指对象的实际类型,在运行期确定。
以上两个定义是我的个人理解,未必准确!如有错误,欢迎留言指出。
这两个定义我都说的指针(或引用),因为我查到的大多数博客里都是用正面的例子来说明,他们说 A* p = new B(); p 的静态类型是 A, 动态类型是 B。
但是对于 A b = B();呢?b 还有没有静态类型和动态类型这一说?我觉得这里面 b 是一个栈区对象,而不是指针,没有所谓的动态类型,它只有一个类型,那就是 A 类型,所以 b 对象调用的是 A 类中的 print 函数。
说完了静态类型和动态类型,接下来说静态绑定和动态绑定。
- 静态绑定:又叫早绑定,绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译阶段。
- 动态绑定:又叫晚绑定,绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行阶段。
一般情况下,虚函数是动态绑定的,非虚函数是静态绑定的,函数的默认参数也是静态绑定的。
举几个例子:
His question was quite vague — can it or can’t it? How should this “can” be understood? Will it report an error? Calling a member function with an object certainly won’t report an error.
What he really meant by “can it” was whether this call can achieve polymorphism. In other words, what is the output of b.print()?
At that time, all I remembered was that polymorphism depends on the object’s type; the object is of type B, so polymorphism should be achievable.
But the actual result is: polymorphism cannot be achieved

I went back and looked up what static binding and dynamic binding are.
What I found were textbook-style definitions, but after reading enough of them, I understood a little more.
Before understanding static binding and dynamic binding, we first need to understand the two concepts of static type and dynamic type.
- Static type: the type at which a pointer (or reference) is declared in the program, determined at compile time.
- Dynamic type: the actual type of the object pointed to by a pointer (or reference), determined at runtime.
The two definitions above are my personal understanding and may not be accurate! If there are any errors, feel free to leave a comment.
I described both definitions in terms of pointers (or references), because most of the blogs I found used positive examples: they said that for A* p = new B();, p’s static type is A and its dynamic type is B.
But what about A b = B();? Does b still have the concepts of static type and dynamic type? I think b here is a stack object rather than a pointer, so it has no so-called dynamic type; it has only one type, which is type A. Therefore, the b object calls the print function in class A.
Now that static type and dynamic type have been covered, let’s talk about static binding and dynamic binding.
- Static binding: also called early binding. It binds to the static type; the corresponding function or attribute depends on the object’s static type, and this happens at the compile stage.
- Dynamic binding: also called late binding. It binds to the dynamic type; the corresponding function or attribute depends on the object’s dynamic type, and this happens at the runtime stage.
In general, virtual functions are dynamically bound, non-virtual functions are statically bound, and default function arguments are also statically bound.
Let me give a few examples:
1 |
|
最后总结一下实现多态的三个必要条件:
- 需要有继承关系,子类继承父类。
- 子类需要重写父类的虚函数。
- 必须存在向上转型:即父类指针或引用指向子类对象。
其余情况均不能实现多态。
Finally, let’s summarize the three necessary conditions for achieving polymorphism:
- There must be an inheritance relationship: the subclass inherits from the parent class.
- The subclass must override the parent class’s virtual function.
- An upcast must exist: a parent class pointer or reference points to a subclass object.
In all other cases, polymorphism cannot be achieved.


