C++——类实例化内存的分配和this指针的使用
2015-05-31 01:05
253 查看
一、类的实例化分配内存
类是结构体的演变,是一种数据类型,如int和char一样是类型。那么在类实例化时,内存是怎样分配的呢?
步骤是:(可以通过代码考证)
1.属性、方法不需要初始化,因为这些全部是指针。
2.初始化派生类的静态字段。
3.初始化派生类的非静态字段。
4.初始化基类的静态字段。
5.初始化基类的非静态字段。
6.调用基类的构造函数。
7.调用派生类的构造函数。
类分为成员变量和成员函数,我们先来讨论成员变量。
一个类对象的地址就是类所包含的这一片内存空间的首地址,这个首地址也就对应具体某一个成员变量的地址。(在定义类对象的同时这些成员变量也就被定义了)我们来以一段代码说明问题:
//类的定义
class K{
public:
K(){k = 12;}
~K(){}
int k;
};
//类的使用
//... K kTemp;
printf("%d--%d\n",&kTemp,&kTemp.k);
printf("%d--%d\n",sizeof(K),sizeof(kTemp.k));
int *i = (int*)(&kTemp);
int w = *i;
printf("%d\n",w); 运行上面的代码,
结果如下:
1310588--1310588
4--4
12
很明显,类的内存大小和其唯一的成员变量的内存大小是一致的。内存地址也是一致的。他们甚至可以相互转换。换成结构体结果也是一样。网友可以自己运行上面代码来进行确认。 这个时候,可能有人会提出疑问了。那么成员函数又如何?上面得代码就好像类没有任何成员函数一样,根本说明不了问题。 呵呵,所有的函数都是存放在代码区的,
不管是全局函数,还是成员函数。要是成员函数占用类的对象空间,那么将是多么可怕的事情:定义一次类对象就有成员函数占用一段空间。 我们再来补充一下静 态成员函数的存放问题吧:静态成员函数与一般成员函数的唯一区别就是没有this指针,因此不能访问非静态数据成员,就像我前面提到的,所有函数都存放在代码区,静态函数也不例外。所有有人一看到 static 这个单词就主观的认为是存放在全局数据区,那是不对的.
当K kTemp 时,(new k()有待考证)就真正在Heap中实例化了一个对象,这个时候也将Heap上的地址写入了K在Stack中的内存地址。K有了Reference,且指向了其在Heap中的对象。
实例化Heap中的对象时,简单的成员变量(貌似还有属性等)一样是继续在Stack上随实例单独分配内存地址。而类中的方法则是由对象们共享的。
二、this的使用
1.this在成员函数的开始前构造,在成员的结束后清除。
这个生命周期同任何一个函数的参数是一样的,没有任何区别。
因为,成员函数默认第一个参数就是this。
举例:
class A{
public:
int func(int p){}
};
func的原型在编译器看来,应该是
int func(A* const this, int p);
即开始执行成员函数之前,构造。
成员函数执行结束,清除。
(2)如果获得一个对象,也不能通过对象使用this指针。
即使是虚函数,当编译器明确调用哪个函数时,也会直接调用,不会通过函数表的指针调用。
6.this指针的作用域
this指针只在非静态函数中存在,所以静态函数不能使用this指针为非静态变量赋值。[待考证]
http://blog.sina.com.cn/s/blog_725dd1010100u12f.html这篇文章的最后有讲解继承的一些概念,以后学习。另外EAX的寄存器是什么?
类是结构体的演变,是一种数据类型,如int和char一样是类型。那么在类实例化时,内存是怎样分配的呢?
步骤是:(可以通过代码考证)
1.属性、方法不需要初始化,因为这些全部是指针。
2.初始化派生类的静态字段。
3.初始化派生类的非静态字段。
4.初始化基类的静态字段。
5.初始化基类的非静态字段。
6.调用基类的构造函数。
7.调用派生类的构造函数。
类分为成员变量和成员函数,我们先来讨论成员变量。
一个类对象的地址就是类所包含的这一片内存空间的首地址,这个首地址也就对应具体某一个成员变量的地址。(在定义类对象的同时这些成员变量也就被定义了)我们来以一段代码说明问题:
//类的定义
class K{
public:
K(){k = 12;}
~K(){}
int k;
};
//类的使用
//... K kTemp;
printf("%d--%d\n",&kTemp,&kTemp.k);
printf("%d--%d\n",sizeof(K),sizeof(kTemp.k));
int *i = (int*)(&kTemp);
int w = *i;
printf("%d\n",w); 运行上面的代码,
结果如下:
1310588--1310588
4--4
12
很明显,类的内存大小和其唯一的成员变量的内存大小是一致的。内存地址也是一致的。他们甚至可以相互转换。换成结构体结果也是一样。网友可以自己运行上面代码来进行确认。 这个时候,可能有人会提出疑问了。那么成员函数又如何?上面得代码就好像类没有任何成员函数一样,根本说明不了问题。 呵呵,所有的函数都是存放在代码区的,
不管是全局函数,还是成员函数。要是成员函数占用类的对象空间,那么将是多么可怕的事情:定义一次类对象就有成员函数占用一段空间。 我们再来补充一下静 态成员函数的存放问题吧:静态成员函数与一般成员函数的唯一区别就是没有this指针,因此不能访问非静态数据成员,就像我前面提到的,所有函数都存放在代码区,静态函数也不例外。所有有人一看到 static 这个单词就主观的认为是存放在全局数据区,那是不对的.
当K kTemp 时,(new k()有待考证)就真正在Heap中实例化了一个对象,这个时候也将Heap上的地址写入了K在Stack中的内存地址。K有了Reference,且指向了其在Heap中的对象。
实例化Heap中的对象时,简单的成员变量(貌似还有属性等)一样是继续在Stack上随实例单独分配内存地址。而类中的方法则是由对象们共享的。
二、this的使用
1.this在成员函数的开始前构造,在成员的结束后清除。
这个生命周期同任何一个函数的参数是一样的,没有任何区别。
因为,成员函数默认第一个参数就是this。
举例:
class A{
public:
int func(int p){}
};
func的原型在编译器看来,应该是
int func(A* const this, int p);
即开始执行成员函数之前,构造。
成员函数执行结束,清除。
2.this指针的的存放位置
(1)this指针的存放位置和编译器相关,可能是栈,寄存器,全局变量区3.this指针的是如何传递给类中函数的
(1)大多数编译器通过eax寄存器传递this指针。在调用之前,编译器会把对应的对象地址放在eax寄存器中4.我们取得一个对象时,可以获取其this指针。如果知道一个对象this指针的位置,能够直接使用吗?
(1)this指针只有在成员函数中才有定义。只有在成员函数中,是可以通过&this获得地址的,也可以直接使用它。(2)如果获得一个对象,也不能通过对象使用this指针。
5.每个类编译后,是否会产生一个类中函数表来保存函数指针?
普通的函数(成员函数,静态函数)都不会产生一个函数表,只有虚函数才会被放入函数表。即使是虚函数,当编译器明确调用哪个函数时,也会直接调用,不会通过函数表的指针调用。
6.this指针的作用域
this指针只在非静态函数中存在,所以静态函数不能使用this指针为非静态变量赋值。[待考证]
http://blog.sina.com.cn/s/blog_725dd1010100u12f.html这篇文章的最后有讲解继承的一些概念,以后学习。另外EAX的寄存器是什么?
相关文章推荐
- DLL的双向头文件
- 由一题讨论C语言中的“指针数组作main函数的形参”即 main(int argc,char *argv[])的使用
- C语言产生随机数
- Unix C语言编程示例
- C/C++ 函数指针,强制转换示例
- 一个简单的C/C++多线程
- C/C++求完数,小提醒
- C++ 实现杨辉三角
- C/C++用Unicode保存字符并输出
- C/C++素数判断(附exe方便不懂编程…
- C++刷题——线段分割平面
- 渣校ACM历程——番外之蓝桥杯决赛
- 【末世旅行之C语言】C语言经典试题小集合
- Error Tips
- 在C++里写一个不能被继承的类
- 汉诺塔的C语言实现
- ubuntu下c语言hello world
- swust oj 1132--Coin-collecting by robot
- swust oj 1139--Coin-row problem
- C++虚函数及虚函数表解析