为什么代码会通过空指针显式调用静态方法?
我在几个旧的项目中看到过这样的代码:
class Class { static void Method() {} }; ((Class*)0)->Method();
此代码包含未定义的行为,因为它包含解引用空指针(不pipe之后会发生什么)。 这真的没有任何意义 – 在那里将types名称提供给编译器,而编写上面代码的人可以写下这个代码:
Class::Method();
后者会好的。
为什么会有人写前代码? 这是一个很好的旧时代的成语吗?
AT&T C ++语言系统(预标准化) 2.0版在1989年将静态成员函数添加到C ++中。 在此之前, static
关键字不能用于声明静态成员函数,因此代码作者使用了变通方法,主要是您已经注意到的一个指向空指针的variables。
在AT&T C ++语言系统2.0版本的选读中 ,Stroustrup在第1-22节中写道:
还有人指出,不可移植的代码,如:
((X*)0)->f();
被用来模拟静态成员函数。 这个技巧是一个定时炸弹,因为迟早有人会使用这种
virtual
的f()
,这个调用将会失败,因为零地址没有X
对象。 即使f()
不是虚拟的,在一些dynamic链接的实现下调用也会失败。
您的代码被编写为在Cfront 1.0下编译,或者是在向语言添加静态成员函数时不知道的人。
成员函数与static
的注释确实是一个难题,因为干杯和hth。 – Alf观察到; Cfront 1.0会拒绝该代码:
error: member Method() cannot be static
所以它最初不可能在那里。 我认为Potatoswatter很可能是正确的; 一旦C ++ 2.0编译器可以保证可用,但没有更新调用代码,以后添加static
文件并强制执行Method
的静态方法属性。 为了证实这一点,你需要采访原始程序员或至less检查源代码控制历史logging(如果存在的话)。