一段代码对C++的理解
2014-03-17 11:12
218 查看
我们先来看一段程序
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、 虚函数。
虚函数对应有一个虚函数地址表,而每个实例对象在创建时,都会创建携带这个一个地址,在调用时通过这个地址正确的调用对应的函数。
搞明白了这两个问题,解释上面的结果我想对每个程序员来说就很容易了。
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、 虚函数。
虚函数对应有一个虚函数地址表,而每个实例对象在创建时,都会创建携带这个一个地址,在调用时通过这个地址正确的调用对应的函数。
搞明白了这两个问题,解释上面的结果我想对每个程序员来说就很容易了。
相关文章推荐
- 构造函数语意学和Data语意学
- 【坐在马桶上看算法】算法5:解密回文——栈
- C语言单链表常见操作
- c++中的.和->区别
- C语言接口与实现创建可重用软件的技术读书笔记(6)---再谈内存管理
- C++11 中值得关注的几大变化(详解)
- C++11中值得关注的几大变化
- The Biggest Changes in C++11 (and Why You Should Care)
- C++中输入输出流getline()函数用法
- C++中输入输出流ifstream/ofstream用法总结
- 2013级C++第4周(春)项目——再和对象找感觉【项目4扩展1(选做)】
- 我推荐的一些C\C++书籍
- const用法总结(C++)
- C语言中的位域
- Java与C/C++有什么区别
- C++0x FAQ中文版:std::function 和 std::bind
- 2013级C++第4周(春)项目——再和对象找感觉【项目4扩展4(选做)】
- 【黑马程序员】C语言学习笔记之枚举(十三)
- 2013级C++第4周(春)项目——再和对象找感觉【项目4扩展3(选做)】
- 黑马程序员_C语言基本运算和流程控制