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++知识库 -> c++ new操作符 -> 正文阅读

[C++知识库]c++ new操作符

C++当中3种new的用法 | Fantacity

近在看侯捷侯老师的著作《STL源码剖析》,书中第二张开始讲到了stl中的allocator的一个简易实现,发现原来cpp中的new其实除了我们平常用的最多的new表达式(new operator)之外,还有剩下两种用法。

1. new operator/delete operator

new operator,也叫new表达式,是我们在cpp中最常见的new的用法,比如:

string *pStr = new string("abd");

这个new表达式完成了两件事情:申请内存和调用类的构造函数初始化对象。

与之相对应的是delete operator(delete 表达式),它完成了两件事情:调用所指向元素的析构函数,然后释放内存空间。

2. operator new(operator new[])/operator delete(operator delete[])

operator new(或者operator new[]),其实是标准库函数,容易和new operator搞混。类似与c当中的malloc库函数,只负责申请一块原始的未命名的内存空间,例如:

void *buffer = ::operator new(sizeof(string));

operator delete(或者 operator delete[]),是标准库函数,类似于c当中free库函数,负责释放内存空间。

标准库点故意了operator new函数和operator delete函数的8个重载版本(c++ primer 中文版第5版,P727),其中前4个版本可能抛出bad_alloc异常,后4个版本则不会抛出异常:

// 这4个版本可能抛出异常

void *operator new(size_t); // 分配一个对象

void *operator new[](size_t); // 分配一个数组

void *operator delete(void*) noexcept; // 释放一个对象

void *operator delete[](void*) noexcept; // 释放一个数组

// 这些版本承若不会抛出异常

void *operator new(size_t, nothorw_t &); // 分配一个对象

void *operator new[](size_t, nothorw_t &); // 分配一个数组

void *operator delete(void*, nothorw_t &) noexcept; // 释放一个对象

void *operator delete[](void*, nothorw_t &) noexcept; // 释放一个数组

其中类型nothrow_t是定义在new头文件中的一个struct,在这个类型中不包含任何成员。noexcept异常说明符用来指定其不抛出异常。
当我们自己定义了全局的operator new函数和operator delete函数后,编译器会优先使用我们自己定义的operator new和operator delete,这样我们就担负起了控制动态内存分配的职责,因此这两个函数必须是正确的。我们也可以定义它们为成员函数,如果同时定义了全局和类的成员函数,优先使用成员函数版本的,如果需要使用全局版本的,可以用作用于运算符::operator new::operator delete

3. placement new

placement new,也叫定位new表达式,它用于在给定的内存中初始化对象(但不分配内存),例如
void *buffer = ::operator new(sizeof(string));
buffer = new(buffer) string(“abd”);

与placement new类似,我们可以通过对象调用析构函数,也可以通过对象的指针或引用调用析构函数,这与调用其他成员函数没什么区别:

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

sp->~string();

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

这里我们可以这么理解,new表达式(new operator)其实可以分解为两部,即先调用new操作符(operator new)申请内存,再调用placement new来初始化对象。

来看一个例子,例子中对3个new的用法都做了举例:

#include <new> // for placement new

#include <string> // for string

#include <iostream> // for cout

using namespace std;

int main(void)

{

void* buffer = ::operator new(sizeof(string)); // operator new

buffer = new(buffer) string("123"); // placement new

cout << *(string*)buffer << endl;

// equals new operator

string* str = new string("123");

cout << *str << endl;

delete str;

::operator delete(buffer);

return 0;

}

4. 什么时候需要用到operator new和placement new

如果我们需要把对象的内存分配操作和对象的初始化操作分离开来,就需要用到operator new 和placement new。其实在stl里面allocator就用到了类似的做法,其中allocate负责向系统申请一块指定大小的内存(operator new),而construct负责在这块内存上根据模板类的类型T来调用T的构造函数初始化内存(placement new)。同理deallocat和destory负责释放内存和析构对象。下面是一个简单的allocator实现,画红线部分即为两种new和两种delete的用法。

简单的allocator实现

c++对new的定义在 #include<new>

针对有些类重载了new操作符的情况,不能够调用c++的new,可以使用::new可以解决。

::是运算符中等级最高的,它分为三种:

1)global scope(全局作用域符),用法(::name)

2)class scope(类作用域符),用法(class::name)

3)namespace scope(命名空间作用域符),用法(namespace::name) 他们都是左关联(left-associativity) 他们的作用都是为了更明确的调用你想要的变量,如在程序中的某一处你想调用全局变量a,那么就写成::a,如果想调用class A中的成员变量a,那么就写成A::a,另外一个如果想调用namespace std中的cout成员,你就写成std::cout(相当于using namespace std;cout)意思是在这里我想用cout对象是命名空间std中的cout(即就是标准库里边的cout) 他们算是C++中的基础,如果运用的好的话,你程序的出错率也许会降很多,

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-17 12:34:54  更:2021-11-17 12:36:02 
 
开发: 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 6:59:13-

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