1. 定位 new (placement new)

1.1 起因

内存分配和初始化分离开

Placement new allows you to construct an object in memory that’s already allocated.

C++早期版本中,allocator类还不是标准库一部分。应用程序调用operator new和operator delete。这两个函数的负责分配或释放内存空间,但是不会构造或销毁对象。

1.2 解决

对于operator new分配的内存空间,用new的定位new形式构造对象。

new (place_address) type
new (place_address) type (initializers)
new (place_address) type [size]
new (place_address) type [size] {braced initializer list}
// place_address必须是一个指针,同时在initializers中提供一个(可能为空的)以逗号分隔的初始值列表,该初始值列表将用于构造新分配的对象。

eg.

char *buf  = new char[sizeof(string)]; // pre-allocated buffer
string *p = new (buf) string("hi");    // placement new
string *q = new string("hi");          // ordinary heap allocation

eg.

we can cluster objects together in a single memory area, select an allocator which is very fast but does no deallocation, use memory mapping, and any other semantic we wish to impose by choosing the pool and passing it as an argument to an object’s placement new operator

class Pool {public:Pool() { /* implementation details irrelevant */ };virtual ~Pool() { /* ditto */ };virtual void *allocate(size_t);virtual void deallocate(void *);static Pool::misc_pool() { return misc_pool_p; /* global MiscPool for general use */ }
};class ClusterPool : public Pool { /* ... */ };
class FastPool : public Pool { /* ... */ };
class MapPool : public Pool { /* ... */ };
class MiscPool : public Pool { /* ... */ };// elsewhere...void *pnew_new(size_t size)
{return Pool::misc_pool()->allocate(size);
}void *pnew_new(size_t size, Pool *pool_p)
{if (!pool_p) {return Pool::misc_pool()->allocate(size);}else {return pool_p->allocate(size);}
}void pnew_delete(void *p)
{Pool *hp = Pool::find_pool(p);// note: if p == 0, then Pool::find_pool(p) will return 0.if (hp) {hp->deallocate(p);}
}// elsewhere...class Obj {public:// misc ctors, dtors, etc.// just a sampling of new/del operatorsvoid *operator new(size_t s)             { return pnew_new(s); }void *operator new(size_t s, Pool *hp)   { return pnew_new(s, hp); }void operator delete(void *dp)           { pnew_delete(dp); }void operator delete(void *dp, Pool*)    { pnew_delete(dp); }void *operator new[](size_t s)           { return pnew_new(s); }void *operator new[](size_t s, Pool* hp) { return pnew_new(s, hp); }void operator delete[](void *dp)         { pnew_delete(dp); }void operator delete[](void *dp, Pool*)  { pnew_delete(dp); }
};// elsewhere...ClusterPool *cp = new ClusterPool(arg1, arg2, ...);Obj *new_obj = new (cp) Obj(arg_a, arg_b, ...);

2. 显式的析构函数调用

就像定位new与使用allocate类似一样,对析构函数的显式调用也与使用destroy很类似。

调用析构函数会销毁对象,但是不会释放内存。

string *sp = new string("a value"); // 分配并初始化一个string对象
sp->~string();

和调用destroy类似,调用析构函数可以清除给定的对象但是不会释放该对象所在的空间。如果需要的话,我们可以重新使用该空间。

C++ Primer 5th笔记(chap 19 特殊工具与技术)定位 new 表达式相关推荐

  1. C++ Primer 5th笔记(chap 19 特殊工具与技术)异常类层次

    1. 类 exception . bad_cast 和 bad_alloc 定 义 了 默 认 构 造 函 数 runtime_error 和 logic_error没有默认构造函数, 但是有一个可以 ...

  2. C++ Primer 5th笔记(chap 19 特殊工具与技术)typeid运算符

    1. typeid运算符(typeid operator) 它允许程序向表达式提问:你的对象是什么类型? typeid表达式的形式是typeid(e),其中e可以是任意表达式或类型的名字,它操作的结果 ...

  3. C++ Primer 5th笔记(chap 19 特殊工具与技术)运行时类型识別RTTI

    1. 运行时类型识别(run-time type identification ) 当我们将这两个运算符用于某种类型的指针或引用, 并且该类型含有虚函数时, 运算符将 使用指针或引用所绑定对象的动态类 ...

  4. C++ Primer 5th笔记(chap 19 特殊工具与技术)type_info 类

    1. type_info 的操作 操作 描述 t1 == t2 如果type_info对象t1和t2表示同一种类型,则返回true t1 != t2 如果type_info对象t1和t2表示不同的类型 ...

  5. C++ Primer 5th笔记(chap 19 特殊工具与技术)typeid

    1. 通常情况下使用 typeid 比较两条表达式的类型是否相同或者比较一条表达式的类型是否与指定的类型相同 Derived *dp = new Derived; Base *bp = dp; // ...

  6. C++ Primer 5th笔记(chap 19 特殊工具与技术)使用 RTTI

    1. RTTI用处 当想为具有继承关系的类实现相等运算符时.对于两个对象来说,如果他们的类型相同并且对应的数据成员取值相同,则我们说这两个类是相等的. class Base {friend bool ...

  7. C++ Primer 5th笔记(chap 19 特殊工具与技术)malloc 函数与 free 函数

    void *operator new (size_t size) {if (void *mem = malloc (size) )return mem;elsethrow bad_alloc ( ); ...

  8. C++ Primer 5th笔记(chap 19 特殊工具与技术)控制内存分配

    1. new void operator new (size_t, void ) ;//不允许重新定义这个版本 string *sp = new string("a value") ...

  9. C++ Primer 5th笔记(chap 19 特殊工具与技术)链接指示: extern “C“

    1. C++程序有时需要调用其他语言编写的函数, C++使用链接指示( linkage directive)指出任意非 C++函数所用的语言 1.1 声明一个非C++函数 // 可能出现在 C++头文 ...

最新文章

  1. POI如何使用已有Excel作为模板二三事
  2. win内置ubuntu安装_win10安装内置ubuntu教程
  3. Exchange 2007 被 SMTP中继***一例
  4. java 先进先出的map_「 深入浅出 」java集合Collection和Map
  5. 人工智障学习笔记——强化学习(3)蒙特卡洛方法
  6. Java摇骰子比大小_还在摇骰子比大小?这几款火热的KTV喝酒游戏你值得收藏
  7. 【Sharepoint】 备份与清理Audit log
  8. 【渝粤教育】广东开放大学 金融机构与金融市场 形成性考核 (57)
  9. 快到起飞 | PP-LCNet在CPU上让模型起飞,精度提升且比MobileNetV3+快3倍
  10. FFmpeg总结(十)用ffmpeg进行在视频中加水印图、加gif图
  11. 易语言 火眼 哈勃 防分析源码
  12. Unity3D游戏开发之路:一月工作总结
  13. SAP PI PO XSLT Mapping of Adapter-Specific Message Attributes
  14. 转行软件测试两个多月,感觉很迷茫,下一步该如何提高自己?
  15. 论文阅读: (ECCV 2022) Content-Oriented Learned Image Compression
  16. python 电路仿真spice_SPICE模型电路仿真器的用法及功能解析
  17. GNN(图神经网络)在反欺诈领域的落地
  18. java 反余弦_Java acos() 方法
  19. R语言rjags使用随机效应进行臭氧数据分析
  20. oracle hint 强制索引

热门文章

  1. 数据库_第一第二第三范式讲解(通俗易懂)
  2. The import java.util cannot be resolved
  3. oracle命令格式,OraCmD(Oracle命令行工具) V3.1 官方版
  4. dvwa如何打开_一篇文章让你搭建自己的Web安全测试平台(Dvwa)
  5. mysql查询无限下级_示例php+mysql查询实现无限下级分类树输出
  6. 成功解决ValueError: Shape of passed values is (33, 1), indices imply (33, 2)
  7. 成功解决cv2.error: OpenCV(4.1.2) C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:182: err
  8. NLP:利用DictVectorizer对使用字典存储的数据进行特征抽取与向量化
  9. Py之Data Base:Python和数据库的那些嘻嘻哈哈事详细攻略
  10. 决策树-缺失值和连续值处理及属性划分