Age-based reference counting solves the problem of cyclic references?

Hello all. I've been playing a little with reference counting ideas, and I came up with an idea that might solve the problem of cyclic references: if a smart pointer remembers all the objects it has touched, and if it knows its age and the age of the objects it has pointed to, the smart pointer can delete the objects if its age is older than the objects it has pointed to. Here is an example: #include <list> #include <iostream> using namespace std; unsigned age = 0; class aged { public: aged() : m_age(-1), m_deleted(0) { } aged(const aged &c) : m_age(-1), m_deleted(0) { } void operator = (const aged &a) { } private: unsigned m_age; unsigned m_deleted; template <class T> friend class ptr; }; template <class T> class ptr { public: explicit ptr(T *value = 0) : m_value(value), m_age(++age) { _acquire(); } ptr(const ptr<T> &p) : m_value(p.m_value), m_age(++age) { _acquire(); } ~ptr() { _release(); m_value = 0; _expire(); } T *operator ->() const { return m_value; } void reset() { _release(); } ptr<T> &operator = (const ptr<T> &p) { _release(); m_value = p.m_value; _acquire(); return *this; } private: T *m_value; unsigned m_age; list<T *> m_remembered; void _acquire() { if (m_value && m_value->m_age > m_age) m_value->m_age = m_age; } void _release() { if (m_value && m_value->m_age >= m_age) m_remembered.push_back(m_value); } void _expire() { for(list<T *>::iterator it = m_remembered.begin(); it != m_remembered.end(); ++it) { T *obj = *it; if (obj->m_age >= m_age && !obj->m_deleted) { ++obj->m_deleted; obj->~T(); --obj->m_deleted; if (!obj->m_deleted) ::operator delete(obj); } } } }; class Foo; class Bar : public aged { public: ptr<Foo> m_foo; Bar() { cout << "Bar()\n"; } ~Bar() { cout << "~Bar()\n"; } }; class Foo : public aged { public: ptr<Bar> m_bar; Foo() { cout << "Foo()\n"; } ~Foo() { cout << "~Foo()\n"; } }; int main() { { ptr<Foo>foo0; { ptr<Foo> foo1(new Foo); foo1->m_bar = ptr<Bar>(new Bar); foo1->m_bar->m_foo = foo1; ptr<Bar> bar1(foo1->m_bar); { ptr<Foo> foo2 = foo1; foo2->m_bar = ptr<Bar>(new Bar); foo0 = foo1; foo1.reset(); } } } return 0; } While there is a referential cycle (foo->bar->foo), all objects are eventually deleted. While the above example doesn't use reference counting, it can be combined with reference counting to solve the issue of cyclic references: objects that their reference count reaches 0 are deleted normally; objects with cycles remain in memory until the oldest pointer to them goes out of scope. In most cases, What do you think?
participants (2)
-
Achilleas Margaritis
-
Mathias Gaunard