7--成员函数指针&面向对象的内存管理

it2025-08-31  8

成员函数指针

// 一个例子 class A { public: A(){} void fun(int,int){} }; // pf是一个指针 // 指向一个类型A的成员函数 // 该成员函数形参为(int,int) // 返回值为void void (A::*pf)(int, int); pf = &A::fun; A a; A *pa = &a; (a.*pf)(10, 10); (pa->*pf)(10, 10); function<void (const A&, int, int)> fcn = &A::fun; vector<A> vec = {...}; find_if(vec.begin(), vec.end(), fcn); function<void (A*, int, int)> fcn = &A::fun; vector<A*> vec = {...}; find_if(vec.begin(), vec.end(), fcn);

内存分配

class A { A(形参列数){...} ~A(){...} ... } c++中一切皆类型[基础数据类型也可视为类型处理]

方式1

- 分配 // 实际执行两步 // - 调用void* operator new(size_t)可定制操作符进行对象A内存空间分配 // - 调用new (p) A(实参列表)不可定制的定位new表达式完成地址a处对象A的构造 A* p = new A(实参列表); // 实际执行两步 // - 调用void* operator new[](size_t)可定制操作符进行10个对象A连续内存空间分配 // - 调用new (pa) A[10]不可定制的定位new表达式完成地址p处开始连续10个对象A的默认构造 A* pa = new A[10]; - 释放 // 实际执行两步 // - 调用p->~A()完成p指向对象A的析构 // - 调用void* operator delete(void*)可定制操作符,完成p指向位置一个A对象大小内存空间的释放 delete p; // - 对数组每个元素pi调用pi->~A()完成pi指向对象A的析构 // - 调用void* operator delete[](void*)可定制操作符,完成p指向位置10个A对象大小内存空间的释放 delete [] pa;

方式2

- 分配 A* p = operator new(sizeof(A)); new (p) A(实参列表); A* pa = operator new(sizeof(A)*10); for(int i = 0; i < 10; i++) { new (p+i) A; } - 释放 p->~A(); operator delete(p); for(int i = 0; i < 10; i++) { (pa+i)->~A(); } operator delete(pa); 注意: - operator new()会调用malloc进行内存分配 malloc分配后返回的指针指向首个可用有效字节位置.在此位置前,还有一部分已分配的内存, 用于记录此返回指针可用的内存空间大小等管理信息. 即malloc实际分配的内容为我们要求的数据区+管理区, 数据区还会有对齐要求,可能分配的数据区比要求的大. 因为上述原因,malloc返回的一个指针,需要相应的调用一次free完成指向的整块空间的分配 对malloc分配的大块空间,多次在此空间不同位置,使用多次free是不允许的. operator new/operator delete分别是malloc/free的简单封装 operator new[]/operator delete[]与operator new/operator delete除了名字差异,没有什么本质差别. 都是malloc/free的简单封装

方式3

std::allocator<T> alloc; - 分配 T* p = alloc.allocate(1); alloc.construct(_p, T()); T *pa = alloc.allocate(10); for(int i = 0; i < 10; i++) { alloc.construct(pa+i, T()); } - 释放 alloc.destroy(p); alloc.deallocate(p, 1); for(int i = 0; i < 10; i++) { alloc.destroy(pa+i); } alloc.deallocate(pa, 10); 注意: - alloc.deallocate(void*, size_t)的参数2一般是被忽略的. 因为如前所述, 一个alloc.allocate(size_t)内部借助malloc返回一块空间 而一个malloc返回的一块空间,也只需也只能通过返回指针调用一次free来释放. 故一般实现alloc.deallocate的参数2是被忽略的.

注意

c++一切皆对象 不可用malloc/free来分配和释放对象 malloc/free完成的是内存空间的分配和释放,不会对分配的对象执行构造[在指定地址调构造函数]和析构[在指定地址调析构函数]. malloc/free是c中分配/释放内存的方式,不适合c++中对象的分配/释放
最新回复(0)