网站首页 > 技术文章 正文
C++是个相当复杂的语言,单单是new和delete这两个关键字,还玩出了不少花样。
通常来说new和delete就是用来完成内存分配和调用构造和析构函数的。
比如:
#include <iostream>
using namespace std;
class MyClass {
public:
explicit MyClass() {
cout << "MyClass constructor" << endl;
}
void hello() {
cout << "HelloWorld" << endl;
return;
}
virtual ~MyClass() {
cout << "MyClass destructor" << endl;
}
};
int main() {
MyClass* t = new MyClass;
t->hello();
delete t;
return 0;
}
运行结果如下:
MyClass constructor
HelloWorld
MyClass destructor
那有没有办法自己定义分配内存的函数呢?
这里就引入了operator new。
operator new函数并不负责调用构造子,但是当我们调用new的时候,他会自动调用operator new分配内存。
class MyClass {
public:
explicit MyClass() {}
void* operator new(size_t t) {
cout << "operator new" << endl;
void* m = std::malloc(t);
return m;
}
void operator delete(void* m) {
cout << "operator delete" << endl;
std::free(m);
return;
}
void hello() {
cout << "HelloWorld" << endl;
return;
}
virtual ~MyClass() {}
};
这里我们在类里面重写了operator new和operator delete。
运行刚才的main函数,输出如下:
operator new
HelloWorld
operator delete
故事还没有完,这两个函数可以单独用来分配内存,能不能单独调用构造子?
这时候就需要使用new的完整形式placement new。
new (<address>) type
当placement new的第一个参数是指针时,他会自动调用operator new(size_t, void*),而这个函数的默认实现是不分配地址,返回传入的指针。所以通过这种调用方式,相当于直接调用了构造子。
比如下面的代码:
int main() {
MyClass* t = (MyClass*) ::operator new(sizeof(MyClass));
cout << "After calling operator new" << endl;
t = ::new (t) MyClass;
t->hello();
t->~MyClass();
::operator delete(t);
return 0;
}
这里在直接调用operator new之后,使用placement new,然后传入一个指针参数,这一步会跳过内存分配,而直接调用constructor。末尾也直接调用析构函数,之后再调用operator delete释放内存。
运行结果如下:
After calling operator new
constructor
HelloWorld
destructor
由于C++的一些特殊应用场合,C++额外定义了operator new/delete和placement new。使得分配内存和调用构造子能够分开。从而可以实现新的内存分配方案。
通常我们是不需要使用这个机制的。
首先在操作系统一层,就会实现一套内存管理机制。
接着在C/C++运行时,也会实现一套内存分配机制。
最后在调用STL的时候,还有一层内存分配机制。
所以如果不是在某些特殊应用场景,很难做出更高效的内存分配机制。
猜你喜欢
- 2024-12-06 2024年C++编程不再推荐使用的功能你还在在用吗?
- 2024-12-06 C++ memcpy的用法,大数据传输与获取
- 2024-12-06 C++中继承的详细介绍以及多态的使用场景
- 2024-12-06 C++“智能指针”并不智能,因为它也不总是知道内存是如何分配的
- 2024-12-06 C++11精要学习:右值引用与完美转发
- 2024-12-06 C/C++编程笔记:详细讲解丨复制构造函数
- 2024-12-06 C++ map用法总结
- 2024-12-06 C#与C++交互开发系列(四):使用C++/CLI进行互操作
- 2024-12-06 C++的map用法
- 2024-12-06 C++基础语法梳理:内存分配和管理
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)