主要的改动是:
采用一个特定的输出接口,通过模板的使用,以及单例模式,
显示“每一行”输出的行号,类名,以及对象的Serial Number
这样就可以很好的跟踪相应的对象走向了。- 1 #include <vector>
- 2 #include <iostream>
- 3
- 4 using std::cout;
- 5 using std::vector;
- 6 using std::endl;
- 7 using std::allocator;
- 8 using std::ostream;
- 9
- 10 class Single
- 11 {
- 12 static Single * instance;
- 13 int curr_number;
- 14
- 15 Single() : curr_number(0) {}
- 16
- 17 public:
- 18 static Single * getSingle()
- 19 {
- 20 if(instance == NULL)
- 21 instance = new Single();
- 22 return instance;
- 23 }
- 24 int getNumber()
- 25 {
- 26 return ++ curr_number;
- 27 }
- 28 };
- 29
- 30 Single * Single::instance = NULL;
- 31
- 32 static int count = 0;
- 33 template<class T>
- 34 ostream & getOutput(ostream & os, T const & t)
- 35 {
- 36
- 37 os << ++count << "\t" << T::class_name << " [ SN= " << t.serial_number << " ] ";
- 38 return os;
- 39 }
- 40
- 41 template<class T>
- 42 class MyAllocator
- 43 {
- 44 private:
- 45 allocator<T> * alloc;
- 46 int serial_number;
- 47
- 48 static const char * class_name;
- 49
- 50 template<class Tx> friend ostream & getOutput(ostream & os, Tx const & a);
- 51
- 52 public:
- 53 template<class T1>
- 54 struct rebind { typedef MyAllocator<T1> other; };
- 55
- 56 typedef size_t size_type;
- 57 typedef ptrdiff_t difference_type;
- 58 typedef T* pointer;
- 59 typedef const T* const_pointer;
- 60 typedef T& reference;
- 61 typedef const T& const_reference;
- 62 typedef T value_type;
- 63
- 64 MyAllocator<T>() throw() : alloc(new allocator<T>), serial_number(Single::getSingle()->getNumber())
- 65 { getOutput(cout, * this) << "MyAllocator : construct myself" << endl; }
- 66
- 67 MyAllocator<T>(MyAllocator<T> const & ma) throw() :
- 68 alloc(new allocator<T>(* ma.alloc)),
- 69 serial_number(Single::getSingle()->getNumber())
- 70 {
- 71 getOutput(cout, * this) << "MyAllocator : copy constructor" << endl;
- 72 }
- 73 ~MyAllocator<T>() throw()
- 74 {
- 75 delete alloc;
- 76 getOutput(cout, * this)<< "Destruct myself" << endl;
- 77 }
- 78
- 79 pointer allocate(size_type __n, const void* = 0)
- 80 {
- 81 getOutput(cout, * this) << "MyAllocator : allocate, size = " << __n << endl;
- 82 return alloc->allocate(__n);
- 83 }
- 84
- 85 void deallocate(pointer __p, size_type)
- 86 {
- 87 getOutput(cout, * this) << "MyAllocator : deallocate" << endl;
- 88 alloc->deallocate(__p, sizeof(size_type));
- 89 }
- 90
- 91 void construct(pointer __p, const T & a)
- 92 {
- 93 getOutput(cout, * this) << "MyAllocator : construct, typeid = " << " size = " << sizeof(a) << endl;
- 94 alloc->construct(__p, a);
- 95 }
- 96
- 97 void destroy(pointer __p)
- 98 {
- 99 getOutput(cout, * this) << "MyAllocator : destroy" << endl;
- 100 alloc->destroy(__p);
- 101 }
- 102 };
- 103
- 104 template<class T> const char * MyAllocator<T>::class_name = "MyAllocator";
- 105
- 106 class Base
- 107 {
- 108 int x1;
- 109 static const char * class_name;
- 110 protected:
- 111 int serial_number;
- 112
- 113 template<class T> friend ostream & getOutput(ostream & os, T const &);
- 114
- 115 public:
- 116 Base() : x1(0), serial_number(Single::getSingle()->getNumber())
- 117 { getOutput(cout, * this) << "Constructor of Base" << endl; }
- 118
- 119 Base(Base const & b) : x1(b.x1), serial_number(Single::getSingle()->getNumber())
- 120 { getOutput(cout, * this) << "Copy constructor of Base" << endl; }
- 121
- 122 virtual ~Base() { hello(); };
- 123 virtual void hello();
- 124 };
- 125
- 126 const char * Base::class_name = "Base";
- 127
- 128
- 129
- 130 void Base::hello()
- 131 {
- 132 getOutput(cout, * this) << "Hello from Base" << endl;
- 133 }
- 134
- 135 class Derived: public Base
- 136 {
- 137 int x2;
- 138 static const char * class_name;
- 139
- 140 template<class T> friend ostream & getOutput(ostream & os, T const &);
- 141 //friend ostream & getOutput(ostream & os, Derived const &);
- 142 //friend ostream & getOutput(ostream & os, Base const &);
- 143
- 144 public:
- 145 Derived() : x2(1)
- 146 {
- 147 getOutput(cout, * this) << "Constructor of Derived" << endl;
- 148 }
- 149
- 150 Derived(Derived const & d) : x2(d.x2), Base(d)
- 151 {
- 152 getOutput(cout, * this) << "Copy constructor of Derived" << endl;
- 153 }
- 154
- 155 virtual ~Derived() { hello(); }
- 156 virtual void hello();
- 157 };
- 158
- 159 const char * Derived::class_name = "Derived";
- 160
- 161 void Derived::hello()
- 162 {
- 163 getOutput(cout, * this) << "Hello from Derived" << endl;
- 164 }
- 165
- 166 int main()
- 167 {
- 168 vector<Base, MyAllocator<Base> > v;
- 169 cout << "Begin to push_back objects" << endl;
- 170 cout << "push back Base" << endl;
- 171 v.push_back(Base());
- 172 cout << "push back Derived" << endl;
- 173 v.push_back(Derived());
- 174
- 175 cout << "Begin to pop_back objects" << endl;
- 176 cout << "pop_back Derived" << endl;
- 177 v.pop_back();
- 178 cout << "pop_back Base" << endl;
- 179 v.pop_back();
- 180
- 181 return 0;
- 182 }
复制代码 输出:- 1 MyAllocator [ SN= 1 ] MyAllocator : construct myself
- 2 MyAllocator [ SN= 2 ] MyAllocator : copy constructor
- 3 MyAllocator [ SN= 1 ] Destruct myself
- Begin to push_back objects
- push back Base
- 4 Base [ SN= 3 ] Constructor of Base
- 5 MyAllocator [ SN= 2 ] MyAllocator : allocate, size = 1
- 6 MyAllocator [ SN= 4 ] MyAllocator : copy constructor
- 7 MyAllocator [ SN= 4 ] Destruct myself
- 8 MyAllocator [ SN= 2 ] MyAllocator : construct, typeid = size = 12
- 9 Base [ SN= 5 ] Copy constructor of Base
- 10 MyAllocator [ SN= 6 ] MyAllocator : copy constructor
- 11 MyAllocator [ SN= 6 ] Destruct myself
- 12 MyAllocator [ SN= 7 ] MyAllocator : copy constructor
- 13 MyAllocator [ SN= 7 ] Destruct myself
- 14 Base [ SN= 3 ] Hello from Base
- push back Derived
- 15 Base [ SN= 8 ] Constructor of Base
- 16 Derived [ SN= 8 ] Constructor of Derived
- 17 MyAllocator [ SN= 2 ] MyAllocator : allocate, size = 2
- 18 MyAllocator [ SN= 9 ] MyAllocator : copy constructor
- 19 MyAllocator [ SN= 9 ] MyAllocator : construct, typeid = size = 12
- 20 Base [ SN= 10 ] Copy constructor of Base
- 21 MyAllocator [ SN= 9 ] Destruct myself
- 22 MyAllocator [ SN= 2 ] MyAllocator : construct, typeid = size = 12
- 23 Base [ SN= 11 ] Copy constructor of Base
- 24 MyAllocator [ SN= 12 ] MyAllocator : copy constructor
- 25 MyAllocator [ SN= 12 ] Destruct myself
- 26 MyAllocator [ SN= 13 ] MyAllocator : copy constructor
- 27 MyAllocator [ SN= 13 ] MyAllocator : destroy
- 28 Base [ SN= 5 ] Hello from Base
- 29 MyAllocator [ SN= 13 ] Destruct myself
- 30 MyAllocator [ SN= 2 ] MyAllocator : deallocate
- 31 Derived [ SN= 8 ] Hello from Derived
- 32 Base [ SN= 8 ] Hello from Base
- Begin to pop_back objects
- pop_back Derived
- 33 MyAllocator [ SN= 2 ] MyAllocator : destroy
- 34 Base [ SN= 11 ] Hello from Base
- pop_back Base
- 35 MyAllocator [ SN= 2 ] MyAllocator : destroy
- 36 Base [ SN= 10 ] Hello from Base
- 37 MyAllocator [ SN= 14 ] MyAllocator : copy constructor
- 38 MyAllocator [ SN= 14 ] Destruct myself
- 39 MyAllocator [ SN= 2 ] MyAllocator : deallocate
- 40 MyAllocator [ SN= 2 ] Destruct myself
复制代码
[ 本帖最后由 key 于 14-5-2009 01:30 编辑 ] |