静态联系关系和动态关联的区别

静态关联和动态关联的区别?
在谭浩强老师的书中关于静态关联和动态关联,有下面这样一段论述:
1,如果是通过对象名调用虚函数,在编译阶段就能确定调用的是哪一个类的虚函数,所以属于静态关联。
2,如果通过基类指针调用虚函数(如
C/C++ code
pt=&point;pt->shapeName();
),在编译阶段无法从语句本身确定调用哪一个类的虚函数,只有在运行时,pt指向某一个类对象之后,才能确定调用的是哪一个类的虚函数,故为动态关联。
这段话让我很迷惑。有一下几个问题请大家帮忙给解答一下:
(1)对象内存的分布是否在编译阶段进行?
(2)2中为什么在编译阶段无法从语句本身确定调用哪一个类的虚函数?在函数调用语句之前已经有一个语句给指针赋值,指针的指向也就确定了,为什么还不能确定调用哪一个类的虚函数?
(3)为什么说“在运行时指针指向某一个对象”?指针是在运行时才起作用的吗?
(4)为什么用对象名可以确定是哪个虚函数,而用已经赋值的指针就不能?
谢谢。

------解决方案--------------------
楼主,珍惜生命,换本好点的教材。
------解决方案--------------------
说谭书垃圾就是垃圾,楼主所贴的这几段关于虚拟函数如何解析的文字又属于谭书的一个错误,而且是颇大的一个概念性的误导。同时,所使用的术语不规范,没有“静态关联”、“动态关联”这样的术语,应该又是他自以为是的“发明”。

实际情况是,只要是虚函数,它的解析方式就一定是通过动态类型来进行的,也就是动态绑定,无论通过对象也好、指针或引用也好,都属于动态绑定的过程。

对于通过对象调用虚函数的情况,只不过由于对象的静态类型和动态类型是一样的,所以从效果上看多态性并没有显式体现出来,但仅仅由于“在编译阶段就能确定调用的是哪一个类的虚函数”,就以为这属于静态绑定,是天大的错误!!
------解决方案--------------------
非虚拟函数的解析才使用静态绑定。
------解决方案--------------------
C/C++ code

T* ptr; //ptr的静态类型为T
....
ptr->fun(); //在T::fun被申明为virtual则, 动态绑定,否则静态绑定
ptr->T::fun(); //静态绑定,不论fun是否为virtal
ptr->(*(&T::fun))(); //静态绑定,不论fun是否为virtal

------解决方案--------------------
探讨

非虚拟函数的解析才使用静态绑定。

------解决方案--------------------
探讨
C/C++ code

T* ptr; //ptr的静态类型为T
....
ptr->fun(); //在T::fun被申明为virtual则, 动态绑定,否则静态绑定
ptr->T::fun(); //静态绑定,不论fun是否为virtal
ptr->(*(&T::fun))(); //静态绑定,不论fun是否为virtal

------解决方案--------------------
探讨
引用:

非虚拟函数的解析才使用静态绑定。


这个不对吧。

------解决方案--------------------
C++ primer并没有谈及final overrider是如何解析的,甚至连final overrider也只有寥寥数字。C++标准的相关条款是这样写的:


10.3 Virtual functions

.......Then in any well-formed class, for each virtual function declared in that class or any of its direct or indirect base classes there is a unique final overrider that overrides that function and every other overrider of that function. The rules for member lookup (10.2) are used to determine the final overrider for a virtual function in the scope of a derived class but ignoring names introduced by using-declarations.

..........

[Note: the interpretation of the call of a virtual function depends on the type of the object for which it is called (the dynamic type), whereas the interpretation of a call of a nonvirtual member function depends only on the type of the pointer or reference denoting that object (the static type) (5.2.2). ]



10.2 Member name lookup

Member name lookup determines the meaning of a name (id-expression) in a class scope (3.3.6). Name lookup can result in an ambiguity, in which case the program is ill-formed. For an id-expression, name lookup begins in the class scope of this; for a qualified-id, name lookup begins in the scope of the nested-name-specifier. Name lookup takes place before access control (3.4, clause 11).