FAQ 33.03 What is an advantage of using pointers and references?

Flexibility, with a likely cost in CPU cycles.

Almost all flexibility in software comes with an extra layer of indirection (arrays, dynamic data structures, recursion, and so on). Not surprisingly, dynamic binding also depends on an extra layer of indirection. So using pointers and references, as opposed to using local and member objects directly, offers additional flexibility in the form of polymorphism and dynamic binding (see FAQ 5.04).

Here is a small hierarchy with a base class and a derived class.

 #include <new> #include <iostream> #include <memory> using namespace std; class Base { public:   virtual ~Base() throw();   virtual void f() throw() = 0; }; typedef auto_ptr<Base> BasePtr; Base::~Base() throw() { } class Derived : public Base { public:   virtual void f() throw(); }; void Derived::f() throw() { cout << "Derived::f()\n"; } 

Here is a class whose objects have-a pair of Derived objects. One of these has-a relationships uses a pointer to an object allocated from the heap (remote ownership; see FAQ 30.08); the other uses a direct member object.

 class Fred { public:   Fred() throw(bad_alloc);  ~Fred() throw();   Fred& operator= (const Fred& a) throw();   Fred(const Fred& a) throw();   void method() throw();   void blahBlah() throw(bad_alloc); private:   BasePtr x_;                                        <-- 1   Derived y_;                                        <-- 2 }; Fred::Fred() throw(bad_alloc) : x_(new Derived()) , y_() { } void Fred::method() throw() {   x_->f();                                           <-- 3   y_.f();                                            <-- 4 } 

(1) Has-a via remote ownership (see FAQ 30.08)

(2) Has-a via direct object containment

(3) May or may not invoke Derived::f() depending on the exact class of *x_

(4) Cannot be changed at runtime; always calls Derived::f()

Note that the behavior of Fred::method() depends on which type of object is pointed to by member x_. Even though the constructor initializes x_ to point to a Derived object, other member functions may change this pointer so that it points to an object of a different derived class, thus changing the behavior of Fred::method() as the following example shows. First, here is a second derived class.

 class Derived2 : public Base { public:   virtual void f() throw(); }; void Derived2::f() throw() { cout << "Derived2::f()\n"; } 

Here is a member function of class Fred that changes pointer x_ so that it points to a Derived2 object rather than a Derived object.

 void Fred::blahBlah() throw(bad_alloc) {   BasePtr x2( new Derived2() );   x_ = x2;                                           <-- 1 }                                                    <-- 2 int main() {   Fred a;   a.method();                                        <-- 3   a.blahBlah();                                      <-- 4   a.method();                                        <-- 5 } 

(1) Safe: Automagically deletes the object formerly pointed to by x_

(2) Safe: x2 will be NULL, so this doesn't delete the new object

(3) a.x_ will point to a Derived

(4) Changes a.x_

(5) a.x_ will point to a Derived2

This shows the flexibility advantages of using pointers and freestore. If the application is database bound or network bound or I/O bound, this sort of flexibility can be used to improve performance in some cases (see FAQ 33.02). However if the application is CPU bound and the Fred object happens to be a bottleneck, read the next FAQ.



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