Download presentation
Presentation is loading. Please wait.
Published byJessie Heath Modified over 9 years ago
1
C++ 程序语言设计 Chapter 12: Dynamic Object Creation
2
Outline Object creation process Overloading new & delete
3
Why create dynamic object? Sometimes you know the exact quantity, type, and lifetime of the objects in your program. But not always. an air-traffic system handle planes an CAD system use shapes a network have notes
4
Dynamic Memory Allocation in C C has always provided the functions malloc( ) and free( ) (along with variants of malloc( )) that allocate storage from the heap (also called the free store) at runtime. see the file - MallocClass.cpp
5
Problems come from “DMA” 1.forget to initialize a object. 2.accidentally do something to the object before you initialize it. 3.hand the wrong-sized object. Improper initialization is responsible for a large portion of programming problems, so it’s especially important to guarantee constructor calls for objects created on the heap.
6
Object creation process When a C++ object is created, two events occur: 1.Storage is allocated for the object. 2.The constructor is called to initialize that storage. Step 2 always happens. Step 1 can occur in: the static storage area-managed by compile the stack-managed by compile the heap-managed by yourself
7
operator new combine all the actions necessary to create an object into a single operator called new in C++. When you create an object with new: 1.allocates enough storage on the heap to hold the object 2.calls the constructor for that storage
8
operator new MyType *fp = new MyType(1,2); the equivalent of malloc(sizeof(MyType)) is called the constructor for MyType is called with the resulting address as the this pointer using (1,2) as the argument list * The default new checks to make sure the memory allocation was successful before passing the address to the constructor.
9
operator delete When you destroy an object with delete: 1.calls the destructor 2.releases the memory (often with a call to free( ))
10
operator delete requires the address of an object delete can be called only for an object created by new If the pointer you’re deleting is zero, nothing will happen, so recommend setting a pointer to zero immediately after you delete it see the file - NewAndDelete.cpp
11
delete void* is probably a bug if you call delete for a void*, operator delete should not call a destructor. see the file - BadVoidPointerDeletion.cpp delete a knows that a points to an Object, the destructor is called and thus the storage allocated for data is released delete b releases the storage for the Object b, but the destructor is not called so there is no release of the memory that data points to So you get a very quiet memory leak
12
new & delete for arrays In C++, you can create arrays of objects on the heap, and (of course) the constructor is called for each object in the array, so there must be a default constructor. MyType* const fp = new MyType[100]; MyType* const fp2 = new MyType; fp is actually the starting address of an array, so it makes sense to select array elements using an expression like fp[3].
13
new & delete for arrays what happens when you destroy the array? delete fp2; delete fp; The destructor will be called for the MyType object pointed to by the given address, and then the storage will be released delete []fp; to give the compiler the information that this is actually the starting address of an array
14
Running out of storage What happens when the operator new( ) cannot find a contiguous block of storage large enough to hold the desired object? A special function called the new- handler is called The default behavior for the new-handler is to throw an exception
15
Running out of storage replace the new-handler by including new.h and then calling set_new_handler( ) with the address of the function you want installed. The new-handler function must take no arguments and have a void return value. see the file - NewHandler.cpp
16
Overloading new & delete The constructor and destructor calls are never under your control (otherwise you might accidentally subvert them), but you can change the storage allocation functions operator new( ) and operator delete( ). 1.efficiency: creating and destroying so many objects of a particular class that it has become a speed bottleneck 2.heap fragmentation: By allocating objects of different sizes it’s possible to break up the heap so that you effectively run out of storage
17
Overloading new & delete you’re changing only the way raw storage is allocated. The compiler will simply call your new instead of the default version to allocate storage, then call the constructor for that storage. delete has a similar limitation.
18
Overloading global new & delete If you overload the global versions, you make the defaults completely inaccessible – you can’t even call them from inside your redefinitions. see the file - GlobalOperatorNew.cpp
19
Overloading global new & delete The overloaded new must take an argument of size_t, it is the size of the object you’re responsible for allocating The overloaded new must return a pointer either to an object of that size (or bigger, if you have some reason to do so), or to zero if you can’t find the memory (in which case the constructor is not called!). The return value of operator new( ) is a void*, not a pointer to any particular type The operator delete( ) takes a void* to memory that was allocated by operator new
20
Overloading new & delete for class When the compiler sees you use new to create an object of your class, it chooses the member operator new( ) over the global version. The global versions of new and delete are used for all other types of objects (unless they have their own new and delete). see the file - Framis.cpp
21
Overloading new & delete for arrays If you overload operator new and delete for a class, those operators are called whenever you create an object of that class. if you create an array of those class objects, the global operator new( ) is called to allocate enough storage for the array all at once, and the global operator delete( ) is called to release that storage. You can control the allocation of arrays of objects by overloading the special array versions of operator new[ ] and operator delete[ ] for the class. see the file - ArrayOperatorNew.cpp
22
Constructor calls MyType* f = new MyType; What happens if the storage allocation in new fails? The constructor is not called in that case, so although you still have an unsuccessfully created object, at least you haven’t invoked the constructor and handed it a zero this pointer see the file - NoMemory.cpp
23
placement new & delete There are two other, less common, uses for overloading operator new( ): 1.You may want to place an object in a specific location in memory. 2.You may want to be able to choose from different allocators when calling new The overloaded operator new( ) can take more than one argument: 1.the first argument is always the size of the object 2.the other arguments can be anything you want X* xp = new(a) X;
24
placement new & delete How to destroy the object ? can call the destructor can not release the memory by the dynamic memory mechanism because it wasn’t allocated on the heap The answer is a very special syntax. You can explicitly call the destructor xp->X::~X(); see the file - PlacementOperatorNew.cpp
25
next… Inheritance & Composition thanks!
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.