Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Mail Systems
Eclipse Documentation

How To Guides
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Problem Solutions
Privacy Policy




Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

Cleaning up
containers of pointers

In Stlshape.cpp, the pointers did not clean themselves up automatically. It would be convenient to be able to do this easily, rather than writing out the code each time. Here is a function template that will clean up the pointers in any sequence container. Note that it is placed in the book s root directory for easy access:

//: :purge.h
// Delete pointers in an STL sequence container.
#ifndef PURGE_H
#define PURGE_H
#include <algorithm>
template<class Seq> void purge(Seq& c) {
typename Seq::iterator i;
for(i = c.begin(); i != c.end(); ++i) {
delete *i;
*i = 0;
// Iterator version:
template<class InpIt> void purge(InpIt begin, InpIt end) {
while(begin != end) {
delete *begin;
*begin = 0;
#endif // PURGE_H ///:~

In the first version of purge( ), note that typename is absolutely necessary. This is exactly the case that keyword was designed to solve: Seq is a template argument, and iterator is something that is nested within that template. So what does Seq::iterator refer to? The typename keyword specifies that it refers to a type, and not something else.

Although the container version of purge( ) must work with an STL-style container, the iterator version of purge( ) will work with any range, including an array.

Here is a rewrite of Stlshape.cpp, modified to use the purge( ) function:

//: C07:Stlshape2.cpp
// Stlshape.cpp with the purge() function.
#include <iostream>
#include <vector>
#include "../purge.h"
using namespace std;
class Shape {
virtual void draw() = 0;
virtual ~Shape() {};
class Circle : public Shape {
void draw() { cout << "Circle::draw << endl; }
~Circle() { cout << "~Circle << endl; }
class Triangle : public Shape {
void draw() { cout << "Triangle::draw << endl; }
~Triangle() { cout << "~Triangle << endl; }
class Square : public Shape {
void draw() { cout << "Square::draw << endl; }
~Square() { cout << "~Square << endl; }
int main() {
typedef std::vector<Shape*> Container;
typedef Container::iterator Iter;
Container shapes;
shapes.push_back(new Circle);
shapes.push_back(new Square);
shapes.push_back(new Triangle);
for(Iter i = shapes.begin(); i != shapes.end(); i++)
} ///:~

When using purge( ), carefully consider ownership issues. If an object pointer is held in more than one container, be sure not to delete it twice, and you don t want to destroy the object in the first container before the second one is finished with it. Purging the same container twice is not a problem because purge( ) sets the pointer to zero once it deletes that pointer, and calling delete for a zero pointer is a safe operation.

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire