#include #include #include #include /** Redirection */ template class redirect { private: R & m_obj; /**< Object */ read_hook m_rhook; /**< Reading hook */ write_hook m_whook; /**< Writing hook */ public: /** Constructor */ redirect(R & obj): m_obj(obj) {} /** Reading */ inline operator T() { return m_rhook(m_obj); } /** Writing */ inline T operator = (const T & rval) { return m_whook(m_obj, rval); } }; // end of template class redirect /** A generic class */ class Gen { private: std::vector m_vals; public: /** Constructor */ Gen() { m_vals.reserve(3); m_vals.push_back("123"); m_vals.push_back("456"); m_vals.push_back("789"); } /** Generic getter */ inline std::string getVal(size_t index) const { std::cout << "getVal(" << index << ") called" << std::endl; if (index < m_vals.size()) return m_vals[index]; return ""; } /** Generic setter */ inline void setVal(size_t index, const std::string & val) { std::cout << "setVal(" << index << ", \"" << val << "\") called" << std::endl; if (index < m_vals.size()) m_vals[index] = val; } }; // end of class Gen /** A specific class */ class Spec: private Gen { private: /** Value reading hook */ template class rval { public: int operator () (Gen & gen) { int val; std::stringstream ss(gen.getVal(index)); ss >> val; return val; } }; // end of template class rval /** Value writing hook */ template class wval { public: int operator () (Gen & gen, int val) { std::stringstream ss; ss << val; gen.setVal(index, ss.str()); return val; } }; // end of template class wval public: redirect, wval<0> > val1; /**< Redirected attr */ redirect, wval<1> > val2; /**< Redirected attr */ redirect, wval<2> > val3; /**< Redirected attr */ Spec(): val1(*this), val2(*this), val3(*this) {} }; // end of class Spec int main() { Spec s; std::cout << "Reading val2..." << std::endl; int val2 = s.val2; std::cout << "Result: " << val2 << std::endl; std::cout << "Writing val3..." << std::endl; s.val3 = 654; std::cout << "Done" << std::endl; std::cout << "Checking val3..." << std::endl; bool ok = 654 == s.val3; std::cout << "Result: " << ok << std::endl; return 0; }