- 论坛徽章:
- 0
|
whyglinux
1、引用记数不是必需的。STL 容器生命周期结束后,所有保存的指向容器内对象的指针、引用和指向容器的迭代器均会失效,这里可以保证同样的策略,不需要引用记数。
2、确实要多一步间接,是我忽略了。但是,由于设计的不同,这个性能损失在某些情况下是可以通过回避使用迭代器而回避的。
- #include <cassert>
- #include <cstdlib>
- #include <cstdio>
- #include <vector>
- #include <algorithm>
- template <typename T>
- struct LordOfDestructor {
- void operator() ( T* pobjt ) {
- delete pobjt;
- }
- };
- template <typename T>
- struct ObjFactory {
- static T *newInstance() {
- return new T();
- }
-
- static T *clone (const T& obj) {
- return new T(obj);
- }
- };
- template <typename T,
- typename Dtor = LordOfDestructor<T>,
- typename Factory = ObjFactory<T> >
- struct container : private std::vector< T* > {
- typedef T& reference;
- typedef const T& const_reference;
- typedef std::vector< T* > base_t;
-
- struct iterator {
- reference operator* () {
- return **iter;
- }
-
- typename base_t::iterator iter;
-
- iterator (typename base_t::iterator i)
- :iter(i)
- {}
- };
-
- // simulation for STL semantics
- T * add (const T& obj) {
- T *rt = Factory::clone(obj);
- base_t::push_back(rt);
- return rt;
- }
-
- // provide more conveniency for allocating and manipulating objects
- T * add (T *p) {
- base_t::push_back(p);
- return p;
- }
-
- void clear() {
- for_each (base_t::begin(), base_t::end(), Dtor());
- }
-
- iterator begin() {
- return iterator(base_t::begin());
- }
-
- ~container() {
- clear();
- }
-
- };
- int main ()
- {
- container<int> c;
- int *p = c.add(2); // Since we'd never reallocate objects (as they're managed by Factory and Dtor)
- container<int>::iterator iter = c.begin();
- printf ("%d\n", *iter);
- *p = 3; // Pointer to obj returned previously would always be valid and safe to use (MT conditions excluded).
- printf ("%d\n", *iter);
- c.add(3);
- iter = c.begin(); // iterator may be invalid
- assert (*iter == 3);
- assert ((void *)&*iter == (void *)p); // but original object always holds.
- system("PAUSE");
- }
复制代码
Quite a few different characteristics between this and STL containers though.. |
|