C++ Primer 5th笔记(chap 19 特殊工具与技术)定位 new 表达式

Posted thefist11

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Primer 5th笔记(chap 19 特殊工具与技术)定位 new 表达式相关的知识,希望对你有一定的参考价值。

1. 定位 new (placement new)

1.1 起因

内存分配和初始化分离开

Placement new allows you to construct an object in memory that’s already allocated.

C++早期版本中,allocator类还不是标准库一部分。应用程序调用operator new和operator delete。这两个函数的负责分配或释放内存空间,但是不会构造或销毁对象。

1.2 解决

对于operator new分配的内存空间,用new的定位new形式构造对象。

new (place_address) type
new (place_address) type (initializers)
new (place_address) type [size]
new (place_address) type [size] {braced initializer list}
// place_address必须是一个指针,同时在initializers中提供一个(可能为空的)以逗号分隔的初始值列表,该初始值列表将用于构造新分配的对象。

eg.

char *buf  = new char[sizeof(string)]; // pre-allocated buffer
string *p = new (buf) string("hi");    // placement new
string *q = new string("hi");          // ordinary heap allocation

eg.

we can cluster objects together in a single memory area, select an allocator which is very fast but does no deallocation, use memory mapping, and any other semantic we wish to impose by choosing the pool and passing it as an argument to an object’s placement new operator

class Pool {
public:
    Pool() { /* implementation details irrelevant */ };
    virtual ~Pool() { /* ditto */ };

    virtual void *allocate(size_t);
    virtual void deallocate(void *);

    static Pool::misc_pool() { return misc_pool_p; /* global MiscPool for general use */ }
};

class ClusterPool : public Pool { /* ... */ };
class FastPool : public Pool { /* ... */ };
class MapPool : public Pool { /* ... */ };
class MiscPool : public Pool { /* ... */ };

// elsewhere...

void *pnew_new(size_t size)
{
   return Pool::misc_pool()->allocate(size);
}

void *pnew_new(size_t size, Pool *pool_p)
{
   if (!pool_p) {
      return Pool::misc_pool()->allocate(size);
   }
   else {
      return pool_p->allocate(size);
   }
}

void pnew_delete(void *p)
{
   Pool *hp = Pool::find_pool(p);
   // note: if p == 0, then Pool::find_pool(p) will return 0.
   if (hp) {
      hp->deallocate(p);
   }
}

// elsewhere...

class Obj {
public:
   // misc ctors, dtors, etc.

   // just a sampling of new/del operators
   void *operator new(size_t s)             { return pnew_new(s); }
   void *operator new(size_t s, Pool *hp)   { return pnew_new(s, hp); }
   void operator delete(void *dp)           { pnew_delete(dp); }
   void operator delete(void *dp, Pool*)    { pnew_delete(dp); }

   void *operator new[](size_t s)           { return pnew_new(s); }
   void *operator new[](size_t s, Pool* hp) { return pnew_new(s, hp); }
   void operator delete[](void *dp)         { pnew_delete(dp); }
   void operator delete[](void *dp, Pool*)  { pnew_delete(dp); }
};

// elsewhere...

ClusterPool *cp = new ClusterPool(arg1, arg2, ...);

Obj *new_obj = new (cp) Obj(arg_a, arg_b, ...);

2. 显式的析构函数调用

就像定位new与使用allocate类似一样,对析构函数的显式调用也与使用destroy很类似。

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

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

和调用destroy类似,调用析构函数可以清除给定的对象但是不会释放该对象所在的空间。如果需要的话,我们可以重新使用该空间。

以上是关于C++ Primer 5th笔记(chap 19 特殊工具与技术)定位 new 表达式的主要内容,如果未能解决你的问题,请参考以下文章

C++ Primer 5th笔记(chap 19 特殊工具与技术)malloc 函数与 free 函数

C++ Primer 5th笔记(chap 19 特殊工具与技术)控制内存分配

C++ Primer 5th笔记(chap 19 特殊工具与技术)使用 RTTI

C++ Primer 5th笔记(chap 19 特殊工具与技术)typeid

C++ Primer 5th笔记(chap 19 特殊工具与技术)定位 new 表达式

C++ Primer 5th笔记(chap 19 特殊工具与技术)成员函数指针