Стандарт C++ 98 (1119566), страница 27
Текст из файла (страница 27)
If the newexpression creates an array of objects of class type, access and ambiguity control are done for the destructor(12.4).17If any part of the object initialization described above71) terminates by throwing an exception and a suitabledeallocation function can be found, the deallocation function is called to free the memory in which theobject was being constructed, after which the exception continues to propagate in the context of the newexpression. If no unambiguous matching deallocation function can be found, propagating the exceptiondoes not cause the object’s memory to be freed. [Note: This is appropriate when the called allocation function does not allocate memory; otherwise, it is likely to result in a memory leak. ]18If the new-expression begins with a unary :: operator, the deallocation function’s name is looked up in theglobal scope. Otherwise, if the allocated type is a class type T or an array thereof, the deallocationfunction’s name is looked up in the scope of T.
If this lookup fails to find the name, or if the allocated typeis not a class type or array thereof, the deallocation function’s name is looked up in the global scope.19A declaration of a placement deallocation function matches the declaration of a placement allocation function if it has the same number of parameters and, after parameter transformations (8.3.5), all parametertypes except the first are identical. Any non-placement deallocation function matches a non-placementallocation function.
If the lookup finds a single matching deallocation function, that function will be called;otherwise, no deallocation function will be called.20If a new-expression calls a deallocation function, it passes the value returned from the allocation functioncall as the first argument of type void*. If a placement deallocation function is called, it is passed thesame additional arguments as were passed to the placement allocation function, that is, the same argumentsas those specified with the new-placement syntax. If the implementation is allowed to make a copy of any__________________71) This may include evaluating a new-initializer and/or calling a constructor.80© ISO/IEC5 ExpressionsISO/IEC 14882:1998(E)5.3.4 Newargument as part of the call to the allocation function, it is allowed to make a copy (of the same originalvalue) as part of the call to the deallocation function or to reuse the copy made as part of the call to the allocation function.
If the copy is elided in one place, it need not be elided in the other.21Whether the allocation function is called before evaluating the constructor arguments or after evaluating theconstructor arguments but before entering the constructor is unspecified. It is also unspecified whether thearguments to a constructor are evaluated if the allocation function returns the null pointer or exits using anexception.5.3.5 Delete1[expr.delete]The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.delete-expression:::opt delete cast-expression::opt delete [ ] cast-expressionThe first alternative is for non-array objects, and the second is for arrays. The operand shall have a pointertype, or a class type having a single conversion function (12.3.2) to a pointer type.
The result has typevoid.2If the operand has a class type, the operand is converted to a pointer type by calling the above-mentionedconversion function, and the converted operand is used in place of the original operand for the remainder ofthis section. In either alternative, if the value of the operand of delete is the null pointer the operationhas no effect. In the first alternative (delete object), the value of the operand of delete shall be a pointerto a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause10).
If not, the behavior is undefined. In the second alternative (delete array), the value of the operand ofdelete shall be the pointer value which resulted from a previous array new-expression.72) If not, thebehavior is undefined. [Note: this means that the syntax of the delete-expression must match the type of theobject allocated by new, not the syntax of the new-expression. ] [Note: a pointer to a const type can bethe operand of a delete-expression; it is not necessary to cast away the constness (5.2.11) of the pointerexpression before it is used as the operand of the delete-expression. ]3In the first alternative (delete object), if the static type of the operand is different from its dynamic type, thestatic type shall be a base class of the operand’s dynamic type and the static type shall have a virtualdestructor or the behavior is undefined.
In the second alternative (delete array) if the dynamic type of theobject to be deleted differs from its static type, the behavior is undefined.73)4The cast-expression in a delete-expression shall be evaluated exactly once. If the delete-expression callsthe implementation deallocation function (3.7.3.2), and if the operand of the delete expression is not thenull pointer constant, the deallocation function will deallocate the storage referenced by the pointer thusrendering the pointer invalid. [Note: the value of a pointer that refers to deallocated storage is indeterminate.
]5If the object being deleted has incomplete class type at the point of deletion and the complete class has anon-trivial destructor or a deallocation function, the behavior is undefined.6The delete-expression will invoke the destructor (if any) for the object or the elements of the array beingdeleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, inreverse order of the completion of their constructor; see 12.6.2).7The delete-expression will call a deallocation function (3.7.3.2).8[Note: An implementation provides default definitions of the global deallocation functionsoperator delete() for non-arrays (18.4.1.1) and operator delete[]() for arrays (18.4.1.2).A C++ program can provide alternative definitions of these functions (17.4.3.4), and/or class-specific__________________72) For non-zero-length arrays, this is the same as a pointer to the first element of the array created by that new-expression.
Zerolength arrays do not have a first element.73) This implies that an object cannot be deleted using a pointer of type void* because there are no objects of type void.81ISO/IEC 14882:1998(E)© ISO/IEC5.3.5 Delete5 Expressionsversions (12.5). ] When the keyword delete in a delete-expression is preceded by the unary :: operator,the global deallocation function is used to deallocate the storage.9Access and ambiguity control are done for both the deallocation function and the destructor (12.4, 12.5).5.4 Explicit type conversion (cast notation)[expr.cast]1The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is a referencetype, otherwise the result is an rvalue. [Note: if T is a non-class type that is cv-qualified, the cv-qualifiersare ignored when determining the type of the resulting rvalue; see 3.10. ]2An explicit type conversion can be expressed using functional notation (5.2.3), a type conversion operator(dynamic_cast, static_cast, reinterpret_cast, const_cast), or the cast notation.cast-expression:unary-expression( type-id ) cast-expression3Types shall not be defined in casts.4Any type conversion not mentioned below and not explicitly defined by the user (12.3) is ill-formed.5The conversions performed by— a const_cast (5.2.11),— a static_cast (5.2.9),— a static_cast followed by a const_cast,— a reinterpret_cast (5.2.10), or— a reinterpret_cast followed by a const_cast,can be performed using the cast notation of explicit type conversion.
The same semantic restrictions andbehaviors apply. If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed. If aconversion can be interpreted in more than one way as a static_cast followed by a const_cast, theconversion is ill-formed. [Example:struct A {};struct I1 : A {};struct I2 : A {};struct D : I1, I2 {};A *foo( D *p ) {return (A*)( p );}// ill-formed static_cast interpretation—end example]6The operand of a cast using the cast notation can be an rvalue of type “pointer to incomplete class type”.The destination type of a cast using the cast notation can be “pointer to incomplete class type”.