The examples we've seen so far are illustrative, but fairly simple. It's useful to see an example that has more complexity so you can see that 232s1811c the STL will work in all situations.
[[ Add a factory method that takes a vector of string]]
The class that will be created as the example will be reasonably complex: it's a bicycle which can have a choice of parts. In addition, you can change the parts during the lifetime of a Bicycle object; this includes the ability to add new parts or to upgrade from standard-quality parts to "fancy" parts. The BicyclePart class is a base class with many different types, and the Bicycle class contains a vector<BicyclePart*> to hold the various combination of parts that may be attached to a Bicycle:
//: CXX:Bicycle.h
// Complex class involving dynamic aggregation
#ifndef BICYCLE_H
#define BICYCLE_H
#include <vector>
#include <string>
#include <iostream>
#include <typeinfo>
class LeakChecker
void print()
~LeakChecker()
void operator++(int)
void operator--(int)
};
class BicyclePart
virtual BicyclePart* clone() = 0;
virtual ~BicyclePart()
friend std::ostream&
operator<<(std::ostream& os, BicyclePart* bp)
friend class Bicycle;
};
enum BPart ;
template<BPart id>
class Part : public BicyclePart
};
class Bicycle
// So you can change parts on a bike (but be
// careful: you must clean up any objects you
// remove from the bicycle!)
VBP& bikeParts()
friend std::ostream&
operator<<(std::ostream& os, Bicycle* b);
static void print(std::vector<Bicycle*>& vb,
std::ostream& os = std::cout);
private:
static int counter;
int id;
VBP parts;
void purge();
};
// Both the Bicycle and the generator should
// provide more variety than this. But this gives
// you the idea.
struct BicycleGenerator
};
#endif // BICYCLE_H ///:~
The operator<< for ostream and Bicycle moves through and calls the operator<< for each BicyclePart, and that prints out the class name of the part so you can see what a Bicycle contains. The BicyclePart::clone( ) member function is necessary in the copy-constructor of Bicycle, since it just has a vector<BicyclePart*> and wouldn't otherwise know how to copy the BicycleParts correctly. The cloning process, of course, will be more involved when there are data members in a BicyclePart.
BicyclePart::partcount is used to keep track of the number of parts created and destroyed (so you can detect memory leaks). It is incremented every time a new BicyclePart is created and decremented when one is destroyed; also, when partcount goes to zero this is reported and if it goes below zero there will be an assert( ) failure.
If you want to change BicycleParts on a Bicycle, you just call Bicycle::bikeParts( ) to get the vector<BicyclePart*> which you can then modify. But whenever you remove a part from a Bicycle, you must call delete for that pointer, otherwise it won't get cleaned up.
Here's the implementation:
//: CXX:Bicycle.cpp
// Bicycle implementation
#include "Bicycle.h"
#include <map>
#include <algorithm>
#include <cassert>
using namespace std;
// Static member definitions:
LeakChecker BicyclePart::lc;
int Bicycle::counter = 0;
Bicycle::Bicycle() : id(counter++) ;
const int bplen = sizeof bp / sizeof *bp;
parts = VBP(bp, bp + bplen);
}
Bicycle::Bicycle(const Bicycle& old)
: parts(old.parts.begin(), old.parts.end())
Bicycle& Bicycle::operator=(const Bicycle& old)
void Bicycle::purge()
}
ostream& operator<<(ostream& os, Bicycle* b)
void Bicycle::print(vector<Bicycle*>& vb,
ostream& os) ///:~
Here's a test:
//: CXX:BikeTest.cpp
// Bicycle
#include "Bicycle.h"
#include <algorithm>
using namespace std;
int main() ///:~
1. Create a heap compactor for all dynamic memory in a particular program. This will require that you control how objects are dynamically created and used (do you overload operator new or does that approach work?). The typically heap-compaction scheme requires that all pointers are doubly-indirected (that is, pointers to pointers) so the "middle tier" pointer can be manipulated during compaction. Consider overloading operator-> to accomplish this, since that operator has special behavior which will probably benefit your heap-compaction scheme. Write a program to test your heap-compaction scheme.
|