﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-做呀么做呀么做游戏-随笔分类-技术及代码</title><link>http://www.cppblog.com/ljjhello/category/3189.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 02 Jun 2008 19:19:32 GMT</lastBuildDate><pubDate>Mon, 02 Jun 2008 19:19:32 GMT</pubDate><ttl>60</ttl><item><title>C++中的关键字new</title><link>http://www.cppblog.com/ljjhello/archive/2007/11/02/35765.html</link><dc:creator>狐狸宝宝</dc:creator><author>狐狸宝宝</author><pubDate>Fri, 02 Nov 2007 08:02:00 GMT</pubDate><guid>http://www.cppblog.com/ljjhello/archive/2007/11/02/35765.html</guid><wfw:comment>http://www.cppblog.com/ljjhello/comments/35765.html</wfw:comment><comments>http://www.cppblog.com/ljjhello/archive/2007/11/02/35765.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ljjhello/comments/commentRss/35765.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ljjhello/services/trackbacks/35765.html</trackback:ping><description><![CDATA[<p>今天闲来无事看代码，看到下面这条语句：new ((void*)(iterator)m_data.m_pBuffer+i) T(x);</p>
<p>其中这个一个template class中的一样语句，T代表类型．<br>晕了，从来没见过new的这种用法，怎么看怎么不爽，网上查资料，才知道new原来也有这么多玄机，转载一下：<br><br>new的过程<br>当我们使用关键字new在堆上动态创建一个对象时，它实际上做了三件事：获得一块内存空间、调用构造函数、返回正确的指针。当然，如果我们创建的是简单类型的变量，那么第二步会被省略。假如我们定义了如下一个类A：<br>class A<br>{<br>&nbsp;&nbsp; int i;<br>public:<br>&nbsp;&nbsp; A(int _i) :i(_i*_i) {}<br>&nbsp;&nbsp; void Say()&nbsp; { printf("i=%d\n", i); }<br>};<br>//调用new：<br>A* pa = new A(3);<br>那么上述动态创建一个对象的过程大致相当于以下三句话（只是大致上）：<br>A* pa = (A*)malloc(sizeof(A));<br>pa-&gt;A::A(3);<br>return pa;<br>虽然从效果上看，这三句话也得到了一个有效的指向堆上的A对象的指针pa，但区别在于，当malloc失败时，它不会调用分配内存失败处理程序new_handler，而使用new的话会的。因此我们还是要尽可能的使用new，除非有一些特殊的需求。<br>new的三种形态<br>到目前为止，本文所提到的new都是指的&#8220;new operator&#8221;或称为&#8220;new expression&#8221;，但事实上在C++中一提到new，至少可能代表以下三种含义：new operator、operator new、placement new。<br>new operator就是我们平时所使用的new，其行为就是前面所说的三个步骤，我们不能更改它。但具体到某一步骤中的行为，如果它不满足我们的具体要求时，我们是有可能更改它的。三个步骤中最后一步只是简单的做一个指针的类型转换，没什么可说的，并且在编译出的代码中也并不需要这种转换，只是人为的认识罢了。但前两步就有些内容了。<br>new operator的第一步分配内存实际上是通过调用operator new来完成的，这里的new实际上是像加减乘除一样的操作符，因此也是可以重载的。operator new默认情况下首先调用分配内存的代码，尝试得到一段堆上的空间，如果成功就返回，如果失败，则转而去调用一个new_hander，然后继续重复前面过程。如果我们对这个过程不满意，就可以重载operator new，来设置我们希望的行为。例如：<br>class A<br>{<br>public:<br>&nbsp;&nbsp; void* operator new(size_t size)<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("operator new called\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ::operator new(size);<br>&nbsp;&nbsp; }<br>};</p>
<p>A* a = new A();<br>这里通过::operator new调用了原有的全局的new，实现了在分配内存之前输出一句话。全局的operator new也是可以重载的，但这样一来就不能再递归的使用new来分配内存，而只能使用malloc了：<br>void* operator new(size_t size)<br>{<br>&nbsp;&nbsp; printf("global new\n");<br>&nbsp;&nbsp; return malloc(size);<br>}<br>相应的，delete也有delete operator和operator delete之分，后者也是可以重载的。并且，如果重载了operator new，就应该也相应的重载operator delete，这是良好的编程习惯。<br>new的第三种形态——placement new是用来实现定位构造的，因此可以实现new operator三步操作中的第二步，也就是在取得了一块可以容纳指定类型对象的内存后，在这块内存上构造一个对象，这有点类似于前面代码中的&#8220;p-&gt;A::A(3);&#8221;这句话，但这并不是一个标准的写法，正确的写法是使用placement new</p>
<img src ="http://www.cppblog.com/ljjhello/aggbug/35765.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ljjhello/" target="_blank">狐狸宝宝</a> 2007-11-02 16:02 <a href="http://www.cppblog.com/ljjhello/archive/2007/11/02/35765.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>