关于new/operator new和delete/operator delete的看法

在看过《 Inside the C++ Object Model》的关于new和delete的语意讲解后,对new和delete有了一定程度上的深入了解~~

当我们使用new给我们的一个对象分配空间的时候。。。new内部的调用实际上是

void* operator new(size_t)

{

   //alloc memory

   //then call class's constructor

}

首先分配了空间。。。但是不会调用我们该类的构造函数

在这期间,则C++的RTTI机制会进行暗箱操作~~~

相应的delete也是如此,RTTI也会对其进行干涉

首先调用该类的析构

然后再进行释放...

然而new是一个运算符,并且可以重载,所以在C++中还有一种威力强大的placement new and placement delete

他的重载则是

void * operator new(size_t t,void *p)

{

   return p;

}

同理,RTTI也会使new调用相应的构造函数

但是我们这样做

char *buf=new char[sizeof(typename)];

typename *obj=(typename*)operator new(sizeof(typename),buf);

//这句则只会在buf的所指向的堆内存处给我这个类分配一个typename长度的空间,但是不会去调用构造函数

obj=new(buf) typename;

//这句则是在buf处分配了空间,并且调用构造函数

这就是placement new的强大之处,我们可以在指定的内存处进行我们的对象的构造

但是,如果现在这个对象不需要了,我们还需要在这片内存上构造我们的另一个该类对象,该如何去做呢?

obj->~typename();//??

这样可以,但是却显的很生硬

delete obj;//??

这句正确,但是同样也释放了obj对象的内存空间,那要怎么做呢?

所以C++也提供了对应placement new的placement delete

可以这样进行调用

delete(buf,obj);

//这句则不会对obj的内存进行释放,只调用析构函数,所以,我们如果要继续在该片内存上构造对象,可以如下

typename *_obj=new(buf) typename;

由此看来,placement new和placement delete的强大之处,可以让程序员更灵活的去操作我们的内存单元,让一片内存连续使用,而省去来回的申请和来回的释放过程,更加的提高了编程的效率。

不过,有一点,placement new和placement delete不支持多态,倘若我们有如下代码

struct Base { int j; virtual void f(); };

struct Derived : Base { void f(); };

void fooBar()

{

Base b;

b.f();// Base::f() invoked b.

~Base();

new ( &b ) Derived; // placement new

b.f(); // which f() invoked?

}

这是原书上的代码,最后一句,我们调用的f()是哪个类的呢?

很多用户都希望调用Derived的f(),因为Base中的f()是virtual的

但事与愿违,经过placement new之后,多态并没有体现出来

大多的编译器编译后都会去调用Base的f()。

综上,new和delete在内部实现上,是如何去分配空间并调用对应类型的构造函数已经很明了。

初始其实和C中的malloc和free一样,但是有了RTTI机制,则会在运行时计算类型,从而决定调用哪个类的构造函数。

RTTI实现时,若类中没有一个虚函数,则将在编译过程中静态的计算类型,更多可以参考《 Inside the C++ Object Model》7.3。

若至少有一个虚函数存在,则RTTI在运行时动态的计算类型。

好了,这是我看过之后所领悟到的,写到这,怕自己忘记了。

 

发表于 @ 2009年09月01日 21:49:00

 

原文链接: https://www.cnblogs.com/zjj9850/archive/2010/09/13/1824861.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    关于new/operator new和delete/operator delete的看法

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/14942

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午2:47
下一篇 2023年2月7日 下午2:48

相关推荐