posts - 23,  comments - 94,  trackbacks - 0

今天实训的某同学给我看了一段简单的代码,蛮有意思
数组不是越界了么?为什么结果还是正确的呢?

#include <iostream>
#include <cstdlib>

using namespace std;

class S
{
public:
 void a()
 {
  cout<<sum<<endl;
 }

private:
 static int sum;
};

int S::sum = 0;

int main()
{
 S sa[10];

 sa[100].a();

 system("pause");
 return 0;
}

代码差不多就是这样,一个类的数组,越界访问一个普通成员函数
这个成员函数只访问了静态成员变量
输出的结果是0,同学的问题是,sa[100]不是越界了么?为什么运行的时候不出错呢?

这个问题是一个初学者提出来的~ 不过要解释清楚还真得有些深度~

我同学说
首先,通过对象调用成员函数,就必须在这个对象存在的前提下吧
那么,sa[100]根本不存在啊,为什么这个调用还合法呢?

开始我也感觉比较诧异,觉得我同学说的没错啊~
然后再仔细想了一想做了如下的解释

普通成员函数的调用,必须得到一个this指针的参数
这就是必须由对象或者由对象的指针或者引用来调用的原因

那么一个类中的普通成员函数,可以解释为这样的形式
以上面的S为例子

S_a(S* pthis)
{
    ....
}

那么之前的 sa[100].a();
就相当于调用的是

S_a( sa + 100*sizeof(S) );

如此一来就清晰很多了

这个函数只访问了类中的静态成员,而类中的静态成员又是存储在静态区
那么就是一个全局变量
那之前的程序看起来其实就像是这样

int S_sum = 0;

void S_a(S* pthis)
{
    cout<<S_sum<<endl;
}

这个函数的参数随便传入的是什么值,都无所谓了
这里的sa[100].a()调用实际上可以解释为

(S)(*(sa+100*sizeof(S))).a();

->

S_a( sa + 100*sizeof(S) );

所以,编译,运行的结果都是正确的~

希望我给我的同学的解释也是正确的~

posted on 2009-08-20 22:10 Charlie 侯杰 阅读(3102) 评论(24)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


by Charlie