IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> More Effective C++ 条款08:了解各种不同意义的new和delete -> 正文阅读

[C++知识库]More Effective C++ 条款08:了解各种不同意义的new和delete

当你写string *ps = new string(“Hands up!”)时,你所使用的new是所谓的new operator,它其实干了两件事:

一、分配足够的内存(实际大小是大于所创建的对象大小)

二、调用对象构造函数,为刚才分配的内存对象设定初值。

new operator永远干这两件事,无论如何你不能改变其行为。

上面的那段代码大约反映以下的行为:

void *mem = operator new(sizeof(string));
call string::string(“Hands up!”) on *mem;//只能由编译器完成,用户是不允许这样操作的,也就是说如果你想建立一个堆对象就必须用new操作符,不能直接像上面一样调用构造函数来初始化堆对象。
string?ps = static_cast<string>(mem);


也就是说operator new仅仅分配内存(就像malloc一样),我们能够做的仅仅是重载operator new,为自己的类创建一个定制的内存管理方案,这也让我有点明白为什么在重载operator new的时候并没有写调用构造函数的代码,但它确实被调用了,原来都是new operator在背后操作。

编译器看到类类型的new或者delete表达式的时候,首先查看该类是否是有operator new或者operator delete成员,如果类定义了自己的new和delete函数,则使用这些函数为对象分配和释放内存,否则调用标准库版本。如果你想定制自己独有的内存分配过程,你应该重载全局的operator new函数,然后使用new操作符,new操作符会调用你定制的operator new。当然你可以显示的调用:: operator new和:: operator delete强制使用全局的库函数。

Placement new

placement new的作用是在一块分配好的原始内存上,构建对象。是一个特殊版本的operator new,成为placement new。

class Widget{
public:
    Widget(int widgetSize);
    ...
};

Widget* constructWidgetInBuffer(void *buffer, int widgetSize)
{
    return new (buffer) Widget(widgetSize);
}

这是new operator的用法之一,其中指定一个额外变量作为new operator“隐式调用 operator new”时所用。于是,被调用的operator new除了接受“一定得有的 size_t变量”外,还接受一个void*参数,指向一块内存,准备用来接受构造好的对象。像这样的operator new就是所谓的placement new.

void* operator new(size_t, void* location)
{
    return location;
}

?以下用法原理:

void *ptr = malloc(sizeof(Kamisato));
Kamisato *kamisato = new(ptr) Kamisato();

这样,编译器就像文章最开始写的那里那样,唯一不同是调用operator new的重载版本,在给定的这个指针(ptr)的位置直接调用构造函数。

void *ptr2 =::operatornew(sizeof(Kamisato), ptr);
Kamisato *kamisato = static_cast<Kamisato *>(ptr2);
kamisato->Kamisato::Kamisato();

事实上形式都没有变,就是多了个参数而已;因为operator的重载版本就是返回那个指针而已,这里的ptr2和ptr指向的是同一个内存地址。

用operator new分配的内存,请用operator delete释放。必须一一对应。

数组

数组的分配需要使用上面的兄弟版本 operator new[],它必须对数组中的每个元素调用其构造函数。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:13:21  更:2022-03-15 22:16:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:57:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码