Allocate storage only if you must

Leave storage allocation up to the class client. In a reference-based language like Object Pascal or Smalltalk, all objects are allocated on the heap. In C++, it's better to treat values the same way you would in C. For example, overload the assignment operator instead of defining a copy function; have the caller pass one in by reference and set it instead of allocating and returning an object. This allows you to treat classes just like primitive types, and in the same style.

By doing so, you can make use of one of C++'s unique features: the ability to have automatic and static objects, and objects as members of classes. No matter how clever or efficient the storage allocator, it can never be as fast as allocating an object on the stack, or as part of another object. If an object can be local to a function, there is no storage allocation overhead. Many objects have very localized scope and do not need to be allocated on the heap.

NOTE There is one exception to the rule about allocating an object and returning a pointer: you must do this when the type of the returned object might vary. A Taligent example is TCollectionOf, which has the virtual function CreateIterator, that returns an iterator for the collection. This is done because different subclasses of TCollectionOf return different subclasses of TIteratorOver. You can't tell until run time what subclass of TCollectionOf you have, so you can't preallocate the iterator; the CreateIterator function must allocate it for you and return it. Any time a function must choose what type of object to return, the function must allocate the object, not the caller.

NOTE It is useful to allow for monomorphic allocation when it's permitted. For example, if you know the type of a collection, you can declare the iterator yourself rather than call CreateIterator.

It is still appropriate for the caller to allocate storage even when the type of the object being passed in might vary, because you can use references, like pointers, polymorphically (that is, you can specify a TSubFoo& to an argument of type TFoo&). The key question is whether the caller or the function must determine the type. In the former case, leave allocation to the client; in the latter, the function must allocate the object on the heap and return it.

[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker