C函数的内存分配机制
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C++函数的内存分配机制(转)
2010-08-24 16:03
1.同一个类的对象
共享同一个成员函数的地址空间,而每个对象有独立的成员变量地址空间,可以说成员函数是类拥有的,成员变量是对象拥有的
2.非虚函数
对于非虚函数的调用,编译器只根据数据类型翻译函数地址,判断调用的合法性,由1可知,这些非虚函数的地址与其对象的内存地址无关(只与该类的成员函数的地址空间相关),故对于一个父类的对象指针,调用非虚函数,不管是给他赋父类对象的指针还是子类对象的指针,他只会调用父类中的函数(只与数据类型(此为类类型)相关,与对象无关)。
3.虚函数
虚拟函数的地址翻译取决于对象的内存地址,而不取决于数据类型(编译器对函数调用的合法性检查取决于数据类型)。如果类定义了虚函数,该类及其派生类就要生成一张虚拟函数表,即vtable。而在类的对象地址空间中存储一个该虚表的入口,占4个字节,这个入口地址是在构造对象时由编译器写入的。所以,由于对象的内存空间包含了虚表入口,编译器能够由这个入口找到恰当的虚函数,这个函数的地址不再由数据类型决定了。故对于一个父类的对象指针,调用虚拟函数,如果给他赋父类对象的指针,那么他就调用父类中的函数,如果给他赋子类对象的指针,他就调用子类中的函数(取决于对象的内存地址)。
虚函数需要注意的大概就是这些个地方了,之前在More effective C++上好像也有见过,不过这次在Visual C++权威剖析这本书中有了更直白的认识,这本书名字很牛逼,看看内容也就那么回事,感觉名不副实,不过说起来也是有其独到之处的,否则也没必要出这种书了。4.如果类包含虚拟成员函数,则将此类的析构函数也定义为虚拟函数
因为派生类对象往往由基类的指针引用,如果使用new操作符在堆中构造派生类对象,并将其地址赋给基类指针,那么最后要使用delete操作符删除这个基类指针(释放对象占用的堆栈)。这时如果析构函数不是虚拟的,派生类的析构函数不会被调用,会产生内存泄露。
5.纯虚拟函数
纯虚拟函数没有函数体,专为派生类提供重载的形式。只要形象的将虚拟函数赋值为0,即定义了纯虚函数,例如void virtual XXXX(char* XXX) = 0;
定义了纯虚函数的类称为抽象基类。抽象基类节省了内存空间,但不能用来实例化对象。其派生类必须重载所有的纯虚函数,否则产生编译错误。
抽象基类虽然不能实例化,为派生类提供一个框架。抽象基类为了派生类提供了虚拟函数的重载形式,可以用抽象类的指针引用派生类的对象,这为虚拟函数的应用准备了必要条件。
C/C++中malloc和new区别
2009-05-13 15: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-18 16:34 609人阅读 (0) Effective item 12
new 分配空间->初始化->构造函数
malloc 分配空间
对象的创建分两步:
1. 数据成员初始化。(参见条款13)
2. 执行被调用构造函数体内的动作。
[cpp]
1.class AA
2.{
3.public:
4. string s;
5.};
6.int main()
7.{
8. AA *a = (AA *)malloc(sizeof(AA));
9. a->s = "abc";
10. system("pause");
11.return 0;
12.}
由于a中的s未被初始化,也就是没有调用string的默认构造函数导致s->s = "abc"异常
使用AA *a = new AA;正常运行
[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.int main()
15.{
16.//AA *a = (AA *)malloc(sizeof(AA));
17.//free(a);
18. AA *a = new AA;
19.delete a;
20. system("pause");
21.return 0;
22.}
显示: