C函数的内存分配机制.docx
《C函数的内存分配机制.docx》由会员分享,可在线阅读,更多相关《C函数的内存分配机制.docx(11页珍藏版)》请在冰豆网上搜索。
C函数的内存分配机制
C++函数的内存分配机制(转)
2010-08-2416:
03
1.同一个类的对象
共享同一个成员函数的地址空间,而每个对象有独立的成员变量地址空间,可以说成员函数是类拥有的,成员变量是对象拥有的
2.非虚函数
对于非虚函数的调用,编译器只根据数据类型翻译函数地址,判断调用的合法性,由1可知,这些非虚函数的地址与其对象的内存地址无关(只与该类的成员函数的地址空间相关),故对于一个父类的对象指针,调用非虚函数,不管是给他赋父类对象的指针还是子类对象的指针,他只会调用父类中的函数(只与数据类型(此为类类型)相关,与对象无关)。
3.虚函数
虚拟函数的地址翻译取决于对象的内存地址,而不取决于数据类型(编译器对函数调用的合法性检查取决于数据类型)。
如果类定义了虚函数,该类及其派生类就要生成一张虚拟函数表,即vtable。
而在类的对象地址空间中存储一个该虚表的入口,占4个字节,这个入口地址是在构造对象时由编译器写入的。
所以,由于对象的内存空间包含了虚表入口,编译器能够由这个入口找到恰当的虚函数,这个函数的地址不再由数据类型决定了。
故对于一个父类的对象指针,调用虚拟函数,如果给他赋父类对象的指针,那么他就调用父类中的函数,如果给他赋子类对象的指针,他就调用子类中的函数(取决于对象的内存地址)。
虚函数需要注意的大概就是这些个地方了,之前在MoreeffectiveC++上好像也有见过,不过这次在VisualC++权威剖析这本书中有了更直白的认识,这本书名字很牛逼,看看内容也就那么回事,感觉名不副实,不过说起来也是有其独到之处的,否则也没必要出这种书了。
4.如果类包含虚拟成员函数,则将此类的析构函数也定义为虚拟函数
因为派生类对象往往由基类的指针引用,如果使用new操作符在堆中构造派生类对象,并将其地址赋给基类指针,那么最后要使用delete操作符删除这个基类指针(释放对象占用的堆栈)。
这时如果析构函数不是虚拟的,派生类的析构函数不会被调用,会产生内存泄露。
5.纯虚拟函数
纯虚拟函数没有函数体,专为派生类提供重载的形式。
只要形象的将虚拟函数赋值为0,即定义了纯虚函数,例如voidvirtualXXXX(char*XXX)=0;
定义了纯虚函数的类称为抽象基类。
抽象基类节省了内存空间,但不能用来实例化对象。
其派生类必须重载所有的纯虚函数,否则产生编译错误。
抽象基类虽然不能实例化,为派生类提供一个框架。
抽象基类为了派生类提供了虚拟函数的重载形式,可以用抽象类的指针引用派生类的对象,这为虚拟函数的应用准备了必要条件。
C/C++中malloc和new区别
2009-05-1315:
56:
32阅读(1132)发表评论
1,malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。
它们都可用于申请动态内存和释放内存。
2,对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。
对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。
由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free.
3,因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete.注意new/delete不是库函数。
4,C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存
new是个操作符,和什么"+","-","="……有一样的地位。
malloc是个分配内存的函数,供你调用的。
new是保留字,不需要头文件支持。
malloc需要头文件库函数支持。
new建立的是一个对象,
malloc分配的是一块内存。
new建立的对象你可以把它当成一个普通的对象,用成员函数访问,不要直接访问它的地址空间
malloc分配的是一块内存区域,就用指针访问好了,而且还可以在里面移动指针。
简而言之:
new是一个操作符,可以重载
malloc是一个函数,可以覆盖
new初始化对象,调用对象的构造函数,对应的delete调用相应的析构函数
malloc仅仅分配内存,free仅仅回收内存
2010-07-1816:
34 609人阅读 (0)
Effectiveitem12
new分配空间->初始化->构造函数
malloc分配空间
对象的创建分两步:
1.数据成员初始化。
(参见条款13)
2.执行被调用构造函数体内的动作。
[cpp]
1.class AA
2.{
3.public:
4. string s;
5.};
6.
7.int main()
8.{
9. AA *a = (AA *)malloc(sizeof(AA));
10. a->s = "abc";
11.
12. system("pause");
13. return 0;
14.}
由于a中的s未被初始化,也就是没有调用string的默认构造函数
导致s->s="abc"异常
使用AA*a=newAA;正常运行
[cpp]
1.class AA
2.{
3.public:
4. AA()
5. {
6. cout << "AA constructor" << endl;
7. }
8. ~AA()
9. {
10. cout << "AA destructor" << endl;
11. }
12. BB s;
13.};
14.
15.int main()
16.{
17. //AA *a = (AA *)malloc(sizeof(AA));
18. //free(a);
19. AA *a = new AA;
20. delete a;
21. system("pause");
22. return 0;
23.}
显示:
BBconstructor //对AA类中成员的初始化过程
AAconstructor //对AA构造函数的调用
AAdestructor //对AA析构函数的调用
BBdestructor
使用malloc无任何显示
初始化列表与构造函数:
初始化列表是复制构造函数的过程即Intialization (const和引用数据只能初始化不可以赋值)(使用初始化列表的对象默认初始化过程不再进行)
构造函数 是赋值过程 即assignment (赋值前已经有了一个默认初始化过程[调用他的默认构造函数] 然后在赋值操作 效率比直接利用初始化列表低)
在构造函数内对成员变量赋初值:
[cpp]
1.class BB
2.{
3.public:
4. BB()
5. {
6. cout << "BB constructor" << endl;
7. }
8. BB(const BB& bv)
9. {
10. a = ;
11. cout << "BB copy constructor" << endl;
12. }
13. ~BB()
14. {
15. cout << "BB destructor" << endl;
16. }
17. const BB& operator=(const BB& bv)
18. {
19. a = ;
20. cout << "BB assignment" << endl;
21. return *this;
22. }
23.
24. int a;
25.};
26.
27.class CC
28.{
29.public:
30. CC()
31. {
32. cout << "CC constructor" << endl;
33. }
34. CC(const CC& cv)
35. {
36. a = ;
37. cout << "CC copy constructor" << endl;
38. }
39. ~CC()
40. {
41. cout << "CC destructor" << endl;
42. }
43.
44. const CC& operator=(const CC& cv)
45. {
46. a = ;
47. cout << "CC assignment" << endl;
48. return *this;
49. }
50. int a;
51.
52.};
53.
54.class AA
55.{
56.public:
57. AA(const BB& bb,const CC& cc)
58. {
59. b = bb;
60. c = cc;
61. }
62. //AA(const BB& bb,const CC& cc):
b(bb), c(cc){}
63. BB b;
64. CC c;
65.};
66.
67.int main()
68.{
69. BB b;
70. CC c;
71. AA *a = new AA(b, c);
72. delete a;
73. system("pause");
74. return 0;
75.}
显示:
BBconstructor //main中b的构造
CCconstructor //main中c的构造
BBconstructor //类AA对BB的默认初始化通过BB的默认构造函数
CCconstructor //类AA对CC的默认初始化通过CC的默认构造函数
BBassignment //类AA构造函数中的赋值
CCassignment //类AA构造函数中的赋值
CCdestructor
BBdestructor
在初始化列表中初始化
[cpp]
1.class BB
2.{
3.public:
4. BB()
5. {
6. cout << "BB constructor" << endl;
7. }
8. BB(const BB& bv)
9. {
10. a = ;
11. cout << "BB copy constructor" << endl;
12. }
13. ~BB()
14. {
15. cout << "BB destructor" << endl;
16. }
17. const BB& operator=(const BB& bv)
18. {
19. a = ;
20. cout << "BB assignment" << endl;
21. return *this;
22. }
23.
24. int a;
25.};
26.
27.class CC
28.{
29.public:
30. CC()
31. {
32. cout << "CC constructor" << endl;
33. }
34. CC(const CC& cv)
35. {
36. a = ;
37. cout << "CC copy constructor" << endl;
38. }
39. ~CC()
40. {
41. cout << "CC destructor" << endl;
42. }
43.
44. const CC& operator=(const CC& cv)
45. {
46. a = ;
47. cout << "CC assignment" << endl;
48. return *this;
49. }
50. int a;
51.
52.};
53.
54.class AA
55.{
56.public:
57. //AA(const BB& bb,const CC& cc)
58. //{
59. // b = bb;
60. // c = cc;
61. //}
62. AA(const BB& bb,const CC& cc):
b(bb), c(cc){}
63. BB b;
64. CC c;
65.};
66.
67.int main()
68.{
69. BB b;
70. CC c;
71. AA *a = new AA(b, c);
72. delete a;
73. system("pause");
74. return 0;
75.}
显示:
BBconstructor //main中b的构造
CCconstructor //main中c的构造
BBcopyconstructor //类AA对BB的初始化列表中的初始化通过BB的复制构造函数 【省去了上例的默认初始化过程】
CCcopyconstructor //类AA对CC的初始化列表中的初始化通过CC的复制构造函数 【省去了上例的默认初始化过程】
CCdestructor
BBdestructor