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