C++对象模型 ch6 Running语义学

1. 关于delete

When the programmer writes

delete pi;
the language requires that operator delete not be applied if pi should be set to 0. Thus the compiler must construct a guard around the call:

if ( pi != 0 )
__delete( pi );

// 所以在删除对象时,没有必要判断指针是否为0.
Note that pi is not automatically reset to 0 and a subsequent dereference, such as

// oops: ill-defined but not illegal
if ( pi && *pi == 5 ) ...

// 释放后,应将指针设置为0

2. 关于new

The general library implementation of operator new is relatively straightforward, although there are two subtleties worth examining. (Note: The following version does not account for exception handling.)

extern void*
operator new( size_t size )
{
if ( size == 0 )
size = 1;

void *last_alloc;
while ( !( last_alloc = malloc( size )))
{
if ( _new_handler )
( *_new_handler )();
else return 0;
}

return last_alloc;
}
Although it is legal to write

new T[ 0 ];
the language requires that each invocation of operator new return a unique pointer. The conventional way of solving this is to return a pointer to a default 1-byte memory chunk (this is why size is set to 1). A second interesting element of the implementation is the need to allow the user-supplied _new_handler(), if present, to possibly free up memory. This is the reason for the loop each time _new_handler() is actually invoked.

3. 数组对象的删除

int array_size = 10;
Point3d *p_array = new Point3d[ array_size ];

Concern over the impact of searching for the array dimension on the performance of the delete operator led to the following compromise. The compiler searches for a dimension size only if the bracket is present. Otherwise, it assumes a single object is being deleted. If the programmer fails to provide the necessary bracket, such as

delete p_array; // oops
then only the first element of the array is destructed. The remaining elements are undestructed, although their associated memory is reclaimed.

4. 书中的例子

// Not at all a good idea 
Point *ptr = new Point3d[ 10 ]; 

What happens, however, when we delete the array of ten Point3d elements addressed by ptr? Obviously, we need the virtual mechanism to kick in to have the expected invocation of both the Point and Point3d destructor ten times, once for each element of the array:

// oops: not what we need! 
// only Point::~Point invoked ... 
delete [] ptr; 

在现在的编译器中不再成立,例如:

#include <iostream> using namespace std; class Manager { }; class Point { public: virtual ~Point() { cout << "dest of Point" << endl; } }; class Point3D : public Point { public: virtual ~Point3D() { cout << "dest of Point3D" << endl; } }; Manager m; int main() { Manager* a = new Manager[0]; Manager* b = new Manager[0]; cout << a << "," << b << endl; delete[] a; Point *p = new Point3D[10]; delete[] p; }
输出:

/home/a/j/nomad2:g++ ch6.CPP ch6.CPP: In function 'int main()': ch6.CPP:30: warning: allocating zero-element array ch6.CPP:31: warning: allocating zero-element array /home/a/j/nomad2:./a.out 0x2d02104,0x2d02106 dest of Point3D dest of Point dest of Point3D dest of Point dest of Point3D dest of Point dest of Point3D dest of Point dest of Point3D dest of Point dest of Point3D dest of Point dest of Point3D dest of Point dest of Point3D dest of Point dest of Point3D dest of Point dest of Point3D dest of Point

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值