C++程序员大挑战之二-令人疑惑的NULL指针!该如何解决

C++程序员大挑战之二----令人疑惑的NULL指针!
请看下面的程序
class   foo
{
public:
foo()   {   m_nVar1   =   100;};
~foo(){};
void   Display()
{
printf(   "   m_nVar2   is   %d ",   m_nVar2   );
}
int   m_nVar1;
static   int   m_nVar2;

};

int   foo::m_nVar2   =   500;

int   main(int   argc,   char*   argv[])
{

foo   *p   =   NULL;
p-> Display();

_getch();
return   0;
}

请问哪种说法是正确的:
A.   程序编译错误。
B.   程序编译正确,但是运行时发生异常
C.   程序编译正确,运行时有时正常,有时发生异常。
D.   程序编译正确,运行时正常

你的选择是哪一个?
=========================================================

------解决方案--------------------
D. 程序编译正确,运行时正常
------解决方案--------------------
D
------解决方案--------------------
A, 没有必要的头文件
------解决方案--------------------
D
------解决方案--------------------
呵呵,楼上的真幽默。
其实关于这个问题我以前也说过不少。

p-> Display();

使得Display()方法中的this参量指向p,这里由于p指向空,所以,this也指空。
但是display()中并没有访问对象p的成员属性,只是访问了类属性——static int m_nVar2
它不在*p所处的存储空间中,而是在全局静态区域。所以这里没有访问空地址的内容,故程序运行时正常。
而如果在Display()方法中访问了m_nVar1,编译连接全通过,发生运行时异常(存储空间受保护情况下)。
------解决方案--------------------
不得不说,楼上的分析得完全正确。

不过我还是实际验证了一下。
如果仅仅使用搂主的代码,在VC6中的确编译不过。
Deleting intermediate files and output files for project 'TC2 - Win32 Debug '.
--------------------Configuration: TC2 - Win32 Debug--------------------
Compiling...
StdAfx.cpp
Compiling...
TC2.cpp
tc2.cpp(13) : error C2065: 'printf ' : undeclared identifier
tc2.cpp(25) : error C2065: 'NULL ' : undeclared identifier
tc2.cpp(25) : error C2440: 'initializing ' : cannot convert from 'int ' to 'class foo * '
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
执行 cl.exe 时出错.

TC2.exe - 1 error(s), 0 warning(s)

加上#include <stdio.h> 就可以编译通过了。
当然,可能这个不是楼主的本意。



------解决方案--------------------
俺选D
------解决方案--------------------
1. 我测试了一下. 在 xp + vc-7_1 的环境下. 加上 #include <iostream> 后, 正常编译连接, 正常运行.

2. 但是我还是选 B. 我的理由是, Display 不是一个静态函数. 应该需要一个对象的实例的呀.

3. 我能想象的是, Display 方法被隐式的当作了 implicitly static member. 这点让我很迷惑. 我的记忆中, 只有 4 个方法可以作为隐式的静态成员方法. 分别是
T::operator new
T::operator delete
T::operator new[]
T::operator delete[]

4. 另外, NULL 不是 C++ 标准的东西, 它是编译器厂商的实现方案. 目前的标准采用的是 0. 如下:
foo *p = 0; // 这样比较标准
C++0x 似乎有意要将引入 nullptr 作为关键字, 专门针对指针. 不过那是后话了.

5. mark一下. lz 的题目出的挺有意思. 坚持下去哦. 希望能把 C++ 的边边角角都扫扫干净.
------解决方案--------------------
zenny_chen(ACE Intercessor) 说得很不错

偶补充一个 :)

void Display()
{
if (this)
printf( " m_nVar1 is %d ", m_nVar1 );
}

这样,你或许可以看出是什么回事情了:)

这个函数访问了 m_nVar1 ,即使是 NULL

对象也不会出错


------解决方案--------------------