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

国庆假期小栖,继续整理第六章的内容。

关于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[N]产生的对象数组释放时必须调用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,它会调用析构函数而不释放内存。

之后会继续整理第六章剩下的内容,关于临时对象的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值