Home
Blog
Code-Blog
Twitter
Downloads
Links / Books
About
|
Websites |
Function wrapper testing the class invariantUsing functions wrappers to test the class invariant Search for: Wrapping C++ Member Function Calls - Bjarne Stroustrup This code is an application for this function wrapper. template<class T, class Pref, class Suf> class Wrap; template<class T, class Suf> class Call_proxy { T* p; mutable bool own; Suf suffix; Call_proxy(T* pp, Suf su) :p(pp) , own(true) , suffix(su) { } // restrict creation Call_proxy& operator=(const Call_proxy&) ; // prevent assignment public: template<class U, class P, class S> friend class Wrap; Call_proxy(const Call_proxy& a) : p(a.p) , own(true) , suffix(a.suffix) { a.own=false; } ~Call_proxy() { if (own) suffix() ; } T* operator->() const { return p; } }; template<class T, class Pref, class Suf> class Wrap { T* p; int* owned; void incr_owned() const { if (owned) ++*owned; } void decr_owned() const { if (owned && --*owned == 0) { delete p; delete owned; } } Pref prefix; Suf suffix; public: Wrap(T& x, Pref pr, Suf su) :p(&x) , owned(0) , prefix(pr) , suffix(su) { } Wrap(T* pp, Pref pr, Suf su) :p(pp) , owned(new int(1)) , prefix(pr) , suffix(su) { } Wrap(const Wrap& a) :p(a.p) , owned(a.owned) , prefix(a.prefix) , suffix(a.suffix) { incr_owned() ; } Wrap& operator=(const Wrap& a) { a.incr_owned() ; decr_owned() ; p = a.p; owned = a.owned; prefix = a.prefix; suffix = a.suffix; return *this; } ~Wrap() { decr_owned() ; } Call_proxy<T,Suf> operator->() const { prefix() ; return Call_proxy<T,Suf>(p,suffix) ; } T* direct() const { return p; } // extract pointer to wrapped object }; template<class T> struct Invariant { T * m_p; Invariant(T * p) : m_p(p){} void operator()() const { m_p->Invariant(); } }; template<class T> struct TestInvariant : public Wrap<T, Invariant<T>, Invariant<T>> { TestInvariant(T &x) : Wrap(x, Invariant<T>(&x), Invariant<T>(&x)) { } }; struct X { void Invariant() { cout << "X::Invariant\n"; } void F() { cout << "X::F\n"; } }; int main() // test program { X x; TestInvariant<X> wx(x); wx->F(); return 0; }
|