Content deleted Content added
→History: grammar |
No edit summary |
||
Line 17:
== Functions ==
The placement new functions are overloads of the non-placement new functions. The declaration of the non-placement new functions, for non-array and array <code>new</code> expressions respectively, are:<ref name=Vermeir2001 /><ref name=Stroustrup1997b /><syntaxhighlight lang="cpp">
void
void
</syntaxhighlight>
The Standard C++ library provides two placement overloads each for these functions. Their declarations are:<ref name=Vermeir2001 /><ref name=Stroustrup1997b /><syntaxhighlight lang="cpp">
void
void
void
void
</syntaxhighlight>
Line 31:
There are also placement delete functions. They are overloaded versions of the non-placement delete functions. The non-placement delete functions are declared as:<ref name=Vermeir2001 /><ref name=Stroustrup1997b /><syntaxhighlight lang="cpp">
void operator delete
void operator delete[]
</syntaxhighlight>
The Standard C++ library provides two placement overloads each for these functions. Their declarations are:<ref name=Vermeir2001 /><ref name=Stroustrup1997b /><syntaxhighlight lang="cpp">
void operator delete
void operator delete
void operator delete[]
void operator delete[]
</syntaxhighlight>
Line 51:
=== Default placement ===
The placement overloads of <code>operator new</code> and <code>operator delete</code> that employ an additional <syntaxhighlight lang="cpp" inline>void *</syntaxhighlight> parameter are used for default placement, also known as ''pointer placement''. Their definitions by the Standard C++ library, which it is not permitted for a C++ program to replace or override, are:<ref name=Vermeir2001 /><ref name=Stroustrup1997b /><ref name=Anderson1998a /><syntaxhighlight lang="cpp">
void
void
void operator delete
void operator delete[]
</syntaxhighlight>
Line 65:
The C++ language does allow a program to call a [[destructor (computer science)|destructor]] directly, and, since it is not possible to destroy the object using a <code>delete</code> expression, that is how one destroys an object that was constructed via a pointer placement new expression. For example:<ref name=SolterKleper2005 /><ref name=SeedCooper2001 />
: <syntaxhighlight lang="cpp">
p->~T()
</syntaxhighlight>
Line 78:
This operator is implemented as:<syntaxhighlight lang="cpp">
void* operator new[](std::size_t count, void* here) { return here
inline void* operator new[]( size_t sz, void* here )▼
{ return here ; }▼
</syntaxhighlight>
Line 90 ⟶ 88:
#include <new>
struct T {}
int main
// Call the function operator new(std::size_t, const std::nothrow_t &) and (if successful) construct the object.
T
if (p) {
// The storage has been allocated and the constructor called.
delete p
} else
; // An error has occurred. No storage has been allocated and no object constructed.
return 0
}
</syntaxhighlight>
Line 110 ⟶ 107:
class A {
public:
void
void deallocate
}
</syntaxhighlight>
And define custom placement allocation and deallocation functions as follows:<ref name=Vermeir2001 /><ref name=Stroustrup1997b /><syntaxhighlight lang="cpp">
▲ return arena.allocate(size) ;
}
void operator delete
▲ arena.deallocate(p) ;
}
</syntaxhighlight>
The program would employ the placement syntax to allocate objects using different instances of the <code>A</code> class as follows:<ref name=Vermeir2001 /><ref name=Stroustrup1997b /><syntaxhighlight lang="cpp">
A first_arena, second_arena
T
T
</syntaxhighlight>
Line 137 ⟶ 131:
The former would resemble:<ref name=Stroustrup1997b /><syntaxhighlight lang="cpp">
▲destroy (T * p, A & arena)
▲ p->~T() ; // First invoke the destructor explicitly.
▲ arena.deallocate(p) ; // Then call the deallocator function directly.
}
</syntaxhighlight>
which would be invoked from a program as:<syntaxhighlight lang="cpp">
A arena
T
/* ... */
destroy(p, arena)
</syntaxhighlight>
The latter would involve simply writing the destructor invocation and delete function call into the program:<ref name=Vermeir2001 /><ref name=Dewhurst2003 /><syntaxhighlight lang="cpp">
A arena
T
/* ... */
p->~T()
operator delete(p, arena)
</syntaxhighlight>
Line 164 ⟶ 156:
Placement new can also be used as a simple debugging tool, to enable programs to print the filename and line number of the source code where a memory allocation has failed. This does not require the inclusion of the Standard C++ library header <code><new></code>, but does require the inclusion of a header that declares four placement functions and a macro replacement for the <code>new</code> keyword that is used in new expressions. For example, such a header would contain:<ref name=Anderson1998a /><ref name=Yongwei2007 /><syntaxhighlight lang="cpp">
#if defined(DEBUG_NEW)
void
void
void operator delete
void operator delete[]
#define New new(__FILE__, __LINE__)
#else
Line 175 ⟶ 167:
This would be employed in a program as follows:<ref name=Anderson1998a /><ref name=Yongwei2007 /><syntaxhighlight lang="cpp">
T
</syntaxhighlight>
Line 184 ⟶ 176:
class NewError {
public:
NewError(const char
/* ... */
} ;
void *
operator new
{
if (void
return p
throw NewError(file, line)
}
</syntaxhighlight>
Line 206 ⟶ 198:
#include <iostream>
struct A {}
struct E {}
class T {
public:
T() { throw E()
}
void * operator new
} void operator delete ( void *, const A & )▼
{std::cout << "Placement delete called." << std::endl;}▼
int main ()▼
A a ;▼
try {▼
T * p = new (a) T ;▼
} catch (E exp) {std::cout << "Exception caught." << std::endl;}▼
}
▲ try {
} catch (E exp) {
}
}
</syntaxhighlight>
|