C++深入解析:new操作符的秘密
需积分: 12 52 浏览量
更新于2024-09-17
1
收藏 35KB DOC 举报
"深入C++基础_new运算符.doc"
在C++编程语言中,`new`关键字扮演着至关重要的角色,特别是在动态内存管理方面。`new`不仅是一个关键字,同时也是一个操作符,它允许我们在程序运行时在堆上分配内存,用于创建对象或数组。由于其复杂性和灵活性,`new`在C++中的应用广泛,但也带来了相应的挑战。
### new的过程
当使用`new`创建对象时,通常会执行以下三个步骤:
1. **内存分配**:`new`首先尝试在堆上获取足够大小的内存块。如果内存不足,系统可能会尝试进行垃圾回收或者调用内存分配失败处理程序(`new_handler`)来尝试释放内存并再次尝试分配。
2. **构造函数调用**:如果内存分配成功,`new`会调用对应的构造函数初始化新分配的对象。对于基本类型的变量,这一步会被忽略,因为它们不需要构造。
3. **返回指针**:最后,`new`返回一个指向新分配内存的指针,供后续代码使用。
举个例子,如果我们有如下的类`A`:
```cpp
class A {
int i;
public:
A(int _i):i(_i*_i) {}
void Say() { printf("i=%d\n", i); }
};
```
使用`new`创建`A`对象的代码:
```cpp
A* pa = new A(3);
```
这等价于执行以下三个步骤,但内存分配失败处理和异常处理等细节未被体现:
```cpp
void* memory = operator_new(sizeof(A)); // 内存分配
new (memory) A(3); // 调用构造函数
A* pa = static_cast<A*>(memory); // 指针转换
```
### new的三种形态
C++中的`new`可以有三种不同的含义:
1. **new operator**:也就是我们通常使用的`new`表达式,它包含了上述的内存分配、对象构造和指针返回。
2. **operator new**:这是一个可以被重载的操作符,负责实际的内存分配。默认情况下,如果内存分配失败,`new`会调用`new_handler`。通过重载`operator new`,我们可以自定义内存分配策略,比如增加日志记录、定制错误处理等。
3. **placement new**:这是一种特殊的`new`形式,它不进行内存分配,而是用于在已知地址处构造对象。这在内存池、对象复用等场景下很有用。
### 自定义`operator new`
下面是一个重载`operator new`的例子:
```cpp
class A {
public:
void* operator new(size_t size) {
printf("operator new called\n");
void* ptr = ::operator new(size); // 调用全局的operator new
if (!ptr) throw std::bad_alloc(); // 处理分配失败
return ptr;
}
};
```
在这个例子中,当我们为`A`类对象调用`new`时,会先打印一条消息,然后调用全局的`operator new`,如果分配失败则抛出异常。
总结起来,深入理解`new`在C++中的作用和工作原理对于编写高效、健壮的代码至关重要。熟练掌握`new`的不同形态和如何自定义`operator new`可以帮助开发者更好地控制内存管理,避免内存泄漏和其他相关问题。
2024-06-30 上传
2022-06-15 上传
136 浏览量
2021-11-08 上传
158 浏览量
2023-04-18 上传
134 浏览量
2022-11-05 上传
2022-11-04 上传
![](https://profile-avatar.csdnimg.cn/default.jpg!1)
h1542565399
- 粉丝: 0
最新资源
- 《深入浅出MFC》2/e中文电子书开放下载
- JSP连接Oracle与SQL Server数据库实战指南
- Win32 API权威指南:全面详解与最新版本应用
- 利用SharePointWebService获取文档属性:ID、文件引用与作者
- ARM-DSP-C-CODE深度解析:嵌入式C/C++编程修炼与Linux移植实战
- 构建网络教学平台:设计与实现策略
- JSP连接Oracle数据库实战指南
- 《Struts in Action》:Java Web框架深度解析
- 使用CVSNT和WinCVS搭建Windows小型软件开发团队CVS系统
- Java面试必备知识点:基础、JSP&Servlet、J2EE与安全
- 使用VB访问WMI:Windows管理工具
- C语言中的系统调用:DOS与BIOS函数示例
- MyEclipse JSF 快速入门教程:从零开始到部署
- Visual C# .NET编程指南
- 使用Apache Struts2构建Web 2.0项目实战
- 终极CSS参考指南:2008版