您的位置:首页 > 编程语言 > C语言/C++

[读书笔记] 深入探索C++对象模型-第六章-执行期语义学(中)

2016-10-08 23:57 501 查看
国庆假期小栖,继续整理第六章的内容。

关于new和delete运算符。

a. 使用new运算符构造对象时, 例如:

Point3d* origin = new Point3d;


会被转化为两个操作:分配空间和调用类的构造函数:

Point3d* origin;
if(origin = __new(sizeof(Point3d)))
{
origin = Point3d::Point3d(origin);
}
同样的,使用delete释放对象时,例如:

delete origin;
会被转化为两步操作:调用类的析构函数和释放内存:

if(0 != origin)
{
Point3d::~Point3d(origin);
__delete(origin);
}
b. 对于数组的new语义,会有vec_new调用产生一整组对象,例如:

Point3d* p_array = new Point3d[10];
通常会被编译为:

Point3d* p_array;
p_array = vec_new(0, sizeof(Point3d), 10, &Point3d::Point3d, &Point3d::~Point3d);
注意针对new p_array
产生的对象数组释放时必须调用delete [] p_array. 
c. Placement operator new语义

Placement new是一个预先定义好的重载的new运算符,其作用是在已经申请好的内存上直接构造对象,例如:

Point2w* ptw = new(arena) Point2w;//arena为已申请内存的地址
arena指向一块内存区,用以放置产生的Pointw对象。他需要两个参数,其实现很简单,将获得的指针(上例中的arena)所指的地址传回:

void* operator new(size_t, void* p)
{
return p;
}
类似于:

Point2w* ptw = (Point2w*) arena;
但这只是该操作符扩充的一半,另一半是将Point2w的构造函数实施与arena所指的地址上:

if(0 != ptw)
{
ptw->Point2w::Point2w();
}
注意,如果placement new在原已存在一个object的内存上构造新的object:

Point2w* ptw = new(arena) Point2w;
//...do something
ptw = new(arena) Point2w;


而现有object有一个析构函数,那么改析构函数不会被调用,我们知道,调用delete object会调用该object的析构函数,但是此处不可以这样做,因为,delete不但会调用析构函数,而且会释放内存,那样arena就不能继续使用了,所以我们需要做的是仅仅调用object的析构函数:

ptw->~Point2w();


注:标准C++提供了placement operator delete,它会调用析构函数而不释放内存。

之后会继续整理第六章剩下的内容,关于临时对象的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++对象模型 new delete
相关文章推荐