Listing 4: The Counted class implementation

 1 class Counted
 2 {
 3    public:
 4 
 5   ~Counted() {}
 6    Counted() : _num_references(0), _instance() {}
 7 
 8    void dismiss () { if (!--_num_references) delete this; }
 9    void     use () { ++_num_references; }
10 
11    operator   Data& () { return  _instance; }
12    operator   Data* () { return &_instance; }
13    Data* operator-> () { return &_instance; }
14 
15    template<class Derived>
16    void dyn_cast() const
17    {
18       dynamic_cast<Derived&>(_instance);
19    }
20 
21    template<class Derived>
22    void dyn_cast()
23    {
24       dynamic_cast<Derived&>(_instance);
25    }
26 
27    private:
28 
29    typedef unsigned int uint;
30 
31    mutable uint _num_references; // Reference counter.
32    Data               _instance;
33 
34    Counted(const Counted&); // Not implemented 
35 
36    public: // New stuff.
37 
38    // One argument.
39 
40    template<class Arg1>
41    Counted(const Arg1& arg1) 
42    : _num_references(0), _instance(arg1) {}
43 
44    template<class Arg1>
45    Counted(Arg1& arg1) 
46    : _num_references(0), _instance(arg1) {}
47 
48    // Two args.
49 
50 #define TEMPLATE template<class Arg1, class Arg2>
51 #define CONSTRUCTOR(Arg1, Arg2)     \
52    Counted(Arg1& arg1, Arg2& arg2)  \
53    : _num_references(0), _instance(arg1, arg2) {}
54 
55 TEMPLATE CONSTRUCTOR(const Arg1, const Arg2)
56 TEMPLATE CONSTRUCTOR(const Arg1,       Arg2)
57 TEMPLATE CONSTRUCTOR(      Arg1, const Arg2)
58 TEMPLATE CONSTRUCTOR(      Arg1,       Arg2)
59 
60 #undef TEMPLATE
61 #undef CONSTRUCTOR
62 
63    // Three args require  8 constructors.
64    // Four  args require 16 constructors.
65    // Five  args require 32 constructors.
66    // Implement when needed.
67 };