xiaorenwuzyh的专栏

C++ new 的基本和高级用法推荐文章 new 的基本用法int *a = new int[5];class A {…} //声明一个类 AA *obj = new A(); //使用 new 创建对象delete []a;delete obj;

这里我们注意,new int[5] 仅仅分配了空间, 但是 new A(),不仅仅为对象obj在队上分配了空间, 而且还调用了 A的构造函数,生成了这个对象。 所以 new A() 这样方式的功能如下: – 在堆上分配空间 – 在分配的空间上调用对象的构造函数 (这也是 new 和 malloc的主要区别,是否调用构造函数)

同理: 在调用 delete obj的时候: 1. 首先调用 这个对象 的析构函数 2. 然后释放这个对象的空间

new 的升级版本 (version 1)

从上面可以看到:new 的功能是 1. 分配空间, 2 调用构造函数。 那么到底是如何实现的呢?

其实 C++ 规定 new 的 这 两个功能分开实现: 1. 分配空间: 调用函数 operator new 来实现。 2. 调用构造函数: 调用 placement new 来实现。

现在有三个 new 了,第一个new就是我们常说的new, 这个new 调用 接下来的两个new 来实现它的功能。 (我们称这个 new 为, new operator,叫做“new 表达式”,因为operator 在 new 后面,所以 叫做 “new 表达式”,也就是关键字)

new关键字 会调用 operator new 分配空间: 这里 operator new 是一个全局的函数,写在一个文件中。当使用 new 关键字 的时候,编译器会自动找到这个函数,并且调用这个函数:这个函数的声明如下:

(std::size_t size) throw(std::bad_alloc) {if (size == 0)size = 1;void* p;while ((p = ::malloc(size)) == 0) { //采用 malloc 分配空间std::new_handler nh = std::get_new_handler();if (nh)nh();::bad_alloc();}return p;}(void* ptr) {if (ptr)::free(ptr); //采用 free 释放空间。}

这个 operator new 函数称为 全局 operator new 。 (这里称为 全局 主要是因为 每个类 还可以 重载 自己的 operator new() 函数)

全局 operator new 分配空间

从上个例子中可以看到, 全局 operator new 分配空间,简单的调用了 malloc() 函数来分配空间。 并没有做任何初始化工作。

现在问题来了: 已经有了一段分配好的空间 ,如何在这个空间上 调动这个类的构造函数,从而真正的创建一个对象呢? (你需要对 对象的 内存模型 有一定的了解)。 解决方案是: placement new

placement new 调用构造函数

placement new 的功能就是 在一个 已经分配好的空间上,调用构造函数,创建一个类。 placement new 就这一个用法,,知道如何用就可以了,它不是一个(写在文件中)函数,是编译器编译时候做的事情。

用法如下:

void *buf = // 在这里为buf分配内存Class *pc = new (buf) Class();

举例子:

class A {…} //声明一个 类 Avoid *buf = malloc(sizeof(A)); //简单地分配空间。A *ojb = new (buf)A(); // 在分配的空间上调用构造函数。

现在问题来了: 这里 的空间可以是任意的空间吗,答案是的! 这里的 “已经分配好的空间” 可以是任何的空间,比如说 可以是栈上的空间!

a;}int buf[sizeof(A)]; //在栈上,分配一个数组 A *obj = new(buf) A(); //在这个数组上构造一个 对象 A。new 的升级版本 (version 2)

我们称上一个 operator new 为 全局operator new ,因为它是一个文件中的函数。 1. 于是我们就可以对 operator new 进行重载了: 2. 重载之后,我们可以在其中自己进行内存分配。(比如说,不使用 malloc进行实现)

但是重载 operator 必须非常的注意! 文章说的非常好, 有非常多的注意事项! 有好处也有坏处, 陈硕的文章 说的也非常好! 值得一看,看不懂别怪我。

这里的升级版本是: 可以在类中重载 operator new 和 placement new。 这个需要在 google 上搜索一下。

new 的用法!

当我们自己重载了 new 之后,就可以进行内存管理了,必须说构造一个内存池! 当然,这是下一篇文章的内容了。

(文章还会在不断的修改的)

才能做到人在旅途,感悟人生,享受人生。

xiaorenwuzyh的专栏

相关文章:

你感兴趣的文章:

标签云: