[Exceptional C++ Style] [Exceptional C++ Sytle] Item 22: To new, Perchance to throw, Part 1: The Many Faces of new.

SPENCE Mike (DP-Hurn) mike.Spence at nats.co.uk
Mon Jan 17 08:45:54 EST 2005


Item 22: To new, perchance to throw, Part 1: The many faces of new.

JG Question 
1: What are the three forms of new provided in the c++ standard?

Guru question 
2: What is class-specific new, and how do you make use if it. Describe any
areas where you need to take particular care when providing your own
class-specific new and delete.
3: In the following code, which operator new is invoked for each of the
lines numbered 1 through 4?

Class Base 
{
pubic:
	static void* operation new(std::size_t, const FastMemory&);
};

class Derived : public Base 
{
// ....
};

Derived* p1 = new Derived;	// 1
Derived* p2 = new (std::nothrow) Derived;	// 2
void* p3 = /* some valid memory that's big enough for a Derived */;
new (p3) Derived;
Derived* p4 = new (FastMemory()) Derived;


Solution

1:
There are 3 forms of new.  All of which live within global scope rather then
std.
 
Plain old new. 
It takes no special additional parameters. 
It actually performs the allocation of space for the object. 
It can fail and if it does, throws a std::bad_alloc exception.  
It is permitted to override this form within code.

In-place new. 
It takes void* as a special additional parameter.  
It does not perform any allocation of space for the object (the void* is
assumed to point to a valid block of memory which is large enough to store
the object being newed).
It cannot fail and throws no exceptions.
It can not be override within code.

No throw, 
It takes a std::nothrow_t as a special parameter.
It actually performs the allocation of space for the object.
It can fail, but rather than an exception, it returns a null pointer if it
does fail.
It is permitted to override this form within code.

2:
While only two of the three global versions of new can be replaced within
programs, it is possible to write class-specific versions of all types.
This means that you can write a class specific in-place new which will be
used instead of the standard global function, and you can add a class
specific nothrow new with or without replacing the global one.

The main point of this item is to show that Name Hiding within Classes works
on the New Operator too.  To recap Name hiding, basically it is when a
compiler requires to carry out a name lookup, it starts in the current scope
(the current class) and looks for the desired name.  If it does not find a
matching name, it moves to the next enclosing scope (to the base class) and
looks for the name there.  This is repeated up the class hierarchy until
either the name is found or the global scope is reached.  If the global
scope is searched and if the name can still not be found the compiler gives
up and a nice error message is normally issued.
Once the name has been found, the compiler uses overloading resolution to
find a suitable matching parameter list for all found named items within
this scope.  Finally it checks access rules to see if the names can be
reached.   If either of these fail, for whatever reason, the compiler gives
up; it does not carry on searching in the next enclosing scope.
Armed with this information and looking at the original question, it becomes
apparent that as the Base class has defined an in-place New operator that
takes a FastMemory reference as it's additional parameter, only call 4 will
compile.

Guideline
If you provide any class-specific new operator, always provide a
class-specific plain (no extra parameters) new.
When doing this, don't forget to include the exception specification.  Also
if possible try and implement it in terms of the global version unless you
really need to add special handling.

Guideline
If you provide any class specific new operator, always also provide a class
specific in-place new.
Again, don't forget the exception specification and try to implement in
terms of the global version.
This will stop any calling code that tries to use an in-place new on your
class from causing the compiler to fall over.  It should be noted also that
the STL uses in-place new extensively.

Guideline
If you provide any class specific new operator, then consider providing a
class specific nothrow new in case users of your class do want to invoke it;
otherwise, it will be hidden by other class specific overloads of new.
Again, don't forget the exception specification and either implement it
using the global nothrow new, or implement it in terms of the class specific
plain new.





**********************************************************************
This email and any files transmitted with it are confidential. If you
are not the intended recipient, please notify our Help Desk. Email
postmaster at nats.co.uk immediately.
You should not copy or use this email or attachment(s) for any purpose
nor disclose their contents to any other person.

NATS computer systems may be monitored and communications 
carried on them recorded, to secure the effective operation of the 
system and for other lawful purposes.  
********************************************************************************************************************************************




More information about the Effective-cpp mailing list