// test_inheritance.cpp (C) 2007 adolfo@di-mare.com /** \file test_inheritance.cpp \brief Shows that class \c lkptr handles inheritance correctly. This program creates a std::vector that contains objects derived form the base class \c Point. The vector contains \c lkptr's to each object which remain after the vectoris destroyed. This also shows that \c lkptr can be used with the standard containers, as their copy semantics work correctly. \code Point |--Circle | +--Cilinder +--Square +--Rectangle __ __ / \ +-----+ +-----------+ / \ | || | | | | * | | || | | | | | \__/ | || +-----+ +-----------+ \__/ \endcode \author Adolfo Di Mare \date 2007. */ #include "lkptr.h" #include // cout #include // sort() #include // std::string #include // std::vector #include // std::map /** Point */ struct Point { virtual lkptr key() const { lkptr res ( new std::string("Point") ); return res; } ///< Returns class name (key). virtual lkptr data() const { lkptr res ( new std::string("\n*") ); return res; } ///< Returns the class figure (data). }; /** Circle */ struct Circle : public Point { virtual lkptr key() const { lkptr res ( new std::string("Circle") ); return res; } ///< Returns class name (key). virtual lkptr data() const { lkptr res ( new std::string("\n __\n / \\\n| |\n \\__/") ); return res; } ///< Returns the class figure (data). }; /** Cilinder */ struct Cilinder : public Circle { virtual lkptr key() const { lkptr res ( new std::string("Cilinder") ); return res; } ///< Returns class name (key). virtual lkptr data() const { lkptr res ( new std::string("\n __\n/ \\\n| ||\n|| |\n| ||\n\\__/") ); return res; } ///< Returns the class figure (data). }; /** Square */ struct Square : public Point { virtual lkptr key() const { lkptr res ( new std::string("Square") ); return res; } ///< Returns class name (key). virtual lkptr data() const { lkptr res ( new std::string("\n+-----+\n| |\n| |\n+-----+") ); return res; } ///< Returns the class figure (data). }; /** Rectangle */ struct Rectangle : public Square { virtual lkptr key() const { lkptr res ( new std::string("Rectangle") ); return res; } ///< Returns class name (key). virtual lkptr data() const { lkptr res ( new std::string( "\n+-----------+\n| |" "\n| |\n+-----------+" ) ); return res; } ///< Returns the class figure (data). }; ///< Rectangle /// Funtor to sort a vector of \c lkptr. struct less_vec { bool operator()( const lkptr& l , const lkptr& r ) { return ( *l->key() < *r->key() ); // return ( *(l->key()) < *(r->key()) ); } ///< l < r ??? }; /// Shows that \c lkptr works well with class hierarchy and the STL. void lkptr_inheritance() { typedef std::map< std::string, // key is class name lkptr, // stores the whole class std::less< std::string > > Map; Map MMM; { // Inner block where VEC[] is defined std::vector< lkptr > VEC(5); VEC[0].reset( new Point() ); VEC[1].reset( new Circle() ); VEC[2].reset( new Cilinder() ); VEC[3].reset( new Square() ); VEC[4].reset( new Rectangle() ); std::sort( VEC.begin() , VEC.end() , less_vec() ); for (size_t i=0; idata()<< std::endl << *VEC[i]->key(); } for (size_t i=0; ikey() , VEC[i]) ); } } // VEC[] gets destroyed, itīs values persist in MMM[]. std::cout << std::endl << std::endl; Map::const_iterator it = MMM.begin(); for ( it = MMM.begin(); it != MMM.end(); ++it ) { std::cout << MMM[ it->first ]->data().value() << "\nMMM[" << it->first << "]" << std::endl; } } int main() { lkptr_inheritance(); } /**< Main test program. Produces the following output: \code std::vector<> std:map<> __ __ / \ / \ | || | || || | || | | || | || \__/ \__/ Cilinder MMM[Cilinder] __ __ / \ / \ | | | | \__/ \__/ Circle MMM[Circle] * * Point MMM[Point] +-----------+ +-----------+ | | | | | | | | +-----------+ +-----------+ Rectangle MMM[Rectangle] +-----+ +-----+ | | | | | | | | +-----+ +-----+ Square MMM[Square] \endcode */ // EOF: test_lkptr.cpp