FAQ 2.07 What are the basics of dynamically allocated (new) objects?

graphics/new_icon.gif

C++ allows objects to be allocated dynamically using the new operator. Dynamic allocation is also known as allocating from the heap. As shown, a Car object can be allocated from the heap using the syntax new Car(). The result is stored in a CarPtr pointer. CarPtr is an alias for an auto_ptr, which is a "safe pointer type." The typedef syntax establishes this alias relationship.

 #include <memory>                                    <-- 1 #include <string> using namespace std; #include "Car.hpp" typedef auto_ptr<Car> CarPtr; void f() {   CarPtr p(new Car());                               <-- 1   p->startEngine();                                  <-- 2   p->tuneRadioTo("AM", 770);                         <-- 3 }                                                    <-- 4 int main() {   f(); } 

(1) This gets the definition for auto_ptr

(1) 1: Create an object

(2) 2: Call a member function

(3) 3: Call another member function

(4) 4: Destroy the Car object

When control flows over the line labeled 1: Create an object, an object is created dynamically (from the heap). The object is pointed to by the pointer p. The object can be accessed from the point it is created until the CarPtr is destroyed at the } (line 4). Note however that the CarPtr can be returned to a caller. This line is analogous to (but not interchangeable with) the C code p = malloc(sizeof(Car)). Note that parameters can be passed to the constructor; e.g., p = new Car(100, 73);.

When control flows over the line labeled 2: Call a member function, the startEngine() member function is called for the object pointed to by p. The line labeled 3: Call another member function is similar, showing how to pass parameters to member functions of dynamically allocated objects.

When control flows over the line labeled 4: Destroy the Car object, the Car object pointed to by p is destroyed. If the Car class has a destructor, the runtime system automagically calls the destructor (dtor) when control flows over this line.

Note that dynamically allocated objects don't have to be destroyed in the same scope that created them. For example, if the function said return p;, the ownership of the Car object is passed back to the function's caller, meaning that the Car object won't be destroyed until the } of the caller (or the caller's caller if the caller does likewise, and so on):

 CarPtr g() {   CarPtr p(new Car());   // ...   return p;                                          <-- 1 } void h() {   CarPtr p = g();                                    <-- 2   // ... }                                                    <-- 3 

(1) The caller is now responsible for deleting the Car object

(2) Ownership is transferred from g() to h() here

(3) The Car object dies here

Note to C programmers: It is generally considered bad form to use raw Car* pointers to hold the result of the new Car() operation. This is a big change from the way pointers are handled in the C language. There are many reasons for this change: the C++ approach makes "memory leaks" less likely (there is no explicit use of free(p) or delete p, so programmers don't have to worry about accidentally forgetting the deallocation code or jumping around the deallocation code), the C++ approach makes "dangling references" less likely (if C-like Car* pointers are used, there is a chance that someone will inadvertently access the memory of the Car object after it is deleted), and the C++ approach makes the code "exception safe" (if a C-like Car* were used, any routine that could throw an exception would have to be wrapped in a try...catch block; see FAQ 2.23).



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net