一段代码对C++的理解

来源:互联网 发布:苹果6s强制锁定4g网络 编辑:程序博客网 时间:2024/06/09 18:39

我们先来看一段程序

class A

{

public:

       A(){};

       ~A(){};

       voidTest1()

       {

              printf("%s","Test1");

       }

 

       voidTest2()

       {

              m= 4;

              printf("%s","Test2");

       }

 

       virtualvoid Test3()

       {

              printf("%s","Test3");

       }

 

       staticvoid Test4()

       {

              n= 1;

              printf("%s","Test4");

       }

protected:

       intm;

       staticint n;

};

 

int A::n = 0;

int _tmain(int argc, _TCHAR* argv[])

{

       A*p = NULL;

       p->Test1();

       p->Test2();

       p->Test3();

       p->Test4();

       return0;

}

 

猜猜分别调用这几个函数会出现什么情况?

 

结果是

    p->Test1();//调用Test1成功

    p->Test2();//调用Test2崩溃

    p->Test3();//调用Test3崩溃

    p->Test4();//调用Test4成功

 

不知道你看到这个结果是个什么感觉,反正对于当年的我是感觉很奇怪的。

 

为了弄清楚这个问题,首先要搞清楚两个问题:

1、   程序在内存中的存放

从低地址到高地址,可分为下面几段:

  

l 预留内存地址

(操作系统维护的内存地址,不可访问)

  

l 程序代码区

(只读,存代码和一些其他的东西);

  

l data段

(存初始化的全局变量和static变量,另外还有文字常量区,常量字符

串就是放在这里,程序结束后有系统释放);

  

l bss段

(存未初始化的全局变量和static变量);

  

l 堆

(由低地址向高地址增长,一般new和malloc分配,由程序员分配释放);

 

l 共享库文件

(调用的库文件,位于堆和栈之间);

  

l 栈

(由高地址向低地址增长,和堆的增长方式相对,对不同的OS来说,栈的初始大小有规定,可以修改,目前默认一般为2M,由编译器自动分配释放);

  

l 再上面存的都是操作系统和内核调用的一些内存地址

 

再来看看上面这个Class A都存放在哪儿?

l  函数Test1(),Test2(),Test3(),Test4()存放在代码段。

l  Static int n 存放在data段。

l  Int m,在实例化一个对象时才会被创建,存在于这个对象。

2、     虚函数。

虚函数对应有一个虚函数地址表,而每个实例对象在创建时,都会创建携带这个一个地址,在调用时通过这个地址正确的调用对应的函数。

 

搞明白了这两个问题,解释上面的结果我想对每个程序员来说就很容易了。



0 0