首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

关于dynamic binding及static binding的考虑

2012-09-27 
关于dynamic binding及static binding的思考先看个例子:C/C++ codeclass A{public:virtural void fun( voi

关于dynamic binding及static binding的思考
先看个例子:

C/C++ code
class A{    public:       virtural void fun( void ){ cout << "A"; return; }};class B : public A{    public:      virtual void fun( void ){ cout << "B"; return; }};int main( void ){    A* p = new B;    p -> A::fun( );    return 0;}

A::fun( )这个叫虚拟函数的静态解析。这是近日在回答一个问题时的类似代码,原来偶对这个问题是比较确定的,但后来细细斟酌,却也未必。问题是:虚拟函数的静态解析属于dynamic binding还是static binding??

有些人可能毫不迟疑地认为应该是static binding,因为对于static binding,一般的定义是编译期确定;但是,对照C++标准,却也未必,C++标准是这样说的:

[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). ]

C++标准明确说了虚拟函数调用是依赖动态类型的,这里并没有加上对qualified-id的例外。那么,按照这个条款,A::fun()也是根据动态类型解析的,解析的目标是找到final overrider,方法是member name lookup:

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.

这个member name lookup是怎样的呢?C++标准是这样描述的:

10.2 Member name lookup

.........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.

上述fun就是一个id-expression,这个条款明确地规定对于一个qualified-id(这个例子中的A::fun),名称搜索从嵌套名称指示符(nested-name-specifier)开始。

也就是说,qualified-id的名称搜索总体上依然属于虚拟函数dynamic binding的搜索方法范畴,但是方法中的一个分支。

于是,这个语义就跟static binding的语义有冲突了,A::fun()是属于dynamic binding呢,还是static binding?这个问题耐人寻味,如果说是C++03标准尚未考虑到的情况,但C++11并没有进行修改。BS、lippmen也没有对这个问题有明确的说明。

欢迎大家踊跃发表看法!

[解决办法]
static binding 

p -> A::fun()的语义是 以p做对象指针 调用 A::fun函数.

明确指明了调用 类A的fun 函数, 无论fun是不是虚函数.
所以这个地方的搜索范围就限定了 A::fun, 
如果类A没有fun,则搜寻其基类.

不可能根据虚函数去动态调用B::fun,
因为B::fun 不是类A的函数.
[解决办法]
学习了~
[解决办法]
因为当年gcc的3个版本给出了x->y->x式的答案变化。
探讨
很诧异 BS 为什么没有正面回答,因为 10.3/15 说的明明白白,莫非发问的时候这句话还不在标准里面?那得多少年以前的事儿了,我看了一下 03 年的标准都有这句啊。

[解决办法]
我觉得是static binding
[解决办法]
探讨

因为当年gcc的3个版本给出了x->y->x式的答案变化。
引用:
很诧异 BS 为什么没有正面回答,因为 10.3/15 说的明明白白,莫非发问的时候这句话还不在标准里面?那得多少年以前的事儿了,我看了一下 03 年的标准都有这句啊。

[解决办法]
那个,y是VC的一贯输出。所以,说是gcc的bug轻率了点,说和标准没关系,则极可能太托大自己了。

探讨
引用:

因为当年gcc的3个版本给出了x->y->x式的答案变化。
引用:
很诧异 BS 为什么没有正面回答,因为 10.3/15 说的明明白白,莫非发问的时候这句话还不在标准里面?那得多少年以前的事儿了,我看了一下 03 年的标准都有这句啊。

看起来 y 像是 gcc 的 bug 了,不过这和标准没有关系。

[解决办法]
探讨

那个,y是VC的一贯输出。所以,说是gcc的bug轻率了点,说和标准没关系,则极可能太托大自己了。

引用:
引用:


因为当年gcc的3个版本给出了x->y->x式的答案变化。
引用:
很诧异 BS 为什么没有正面回答,因为 10.3/15 说的明明白白,莫非发问的时候这句话还不在标准里面?那得多少年以前的事儿了,我看了一下……


[解决办法]
我貌似记得mayers反复教导我们,不要轻言自己或者编译器错了。
gcc的作者们,可能哪个都比我们更认真研究过标准的原文。

[解决办法]
探讨

对于这样的代码,我一贯绕着走,基本不想去搞清楚。
搞清楚了也没用的东西。

[解决办法]
探讨
A::fun( )这个叫虚拟函数的静态解析。这是近日在回答一个问题时的类似代码,原来偶对这个问题是比较确定的,但后来细细斟酌,却也未必。问题是:虚拟函数的静态解析属于dynamic binding还是static binding??

有些人可能毫不迟疑地认为应该是static binding,因为对于static binding,一般的定义是编译期确定;但是,对照C++标准,却也未必,C++标准是这样说的:

[解决办法]
当然应该是静态绑定的.
即使标准里面有些许文字和这个语义冲突,也不应该去咬文嚼字,要从整体上领略其设计原则。标准也是人订的,是人都可能犯错,谁能保证那么大的一个文案里面每一个脚注都面面俱到?

对于虚函数调用(the call of a virtual function)来说,加 A:: 这样的限定词是没有任何意义的,虚函数用的是运行时的对象的动态信息。而像 A:: 这样的类型信息是编译时的,在运行时已经不存在了。 如果把 p->A::fun( ); 按动态绑定来处理,那里面的 A:: 没有任何意义, C++ 就应该禁止这种语法。 

而另一方面,即使是虚函数,也有直接调用它的需求. C++ 要满足这种需求,必须提供某种语法来支持,显然 p->A::fun() 正是为此而设计的。

热点排行