/**/ /*Runtime Concept 的模拟(3)虚函数转发,太间接了。改之。基本原理:1. 自己实现vtable。2. 同时转发<T>的new和delete,实现存值。缺陷:1. 成员函数的调用方法不知道是不是符合标准,不过估计移植性没什么问题。2. static应该改为多线程安全的Singleton。3. 太复杂。另:1. VC的非虚成员函数指针居然可以指向虚函数并正常调用,诡异。2. 引用方式的concept只要去掉new和delete的调用即可。*/ #include < stdio.h > #include < vector > #include < algorithm > #include < string > typedef FILE * monitor; struct Rectangle ... { void draw(monitor device) const ...{ fprintf(device, "Rectangle.draw "); } void draw() const ...{ printf("Rectangle.draw ? "); }} ; struct Ellipse ... { virtual void draw(monitor device) const ...{ fprintf(device, "Ellipse.draw virtual "); }} ; struct Triangle ... { int draw(monitor device, int another_arg) const ...{ fprintf(device, "Triangle.draw? "); return 0; }} ; void drawShape( const Rectangle & refShape, monitor device) ... { refShape.draw(device);} void drawShape( const Ellipse & refShape, monitor device) ... { refShape.draw(device);} void drawShape( const Triangle & refShape, monitor device) ... { refShape.draw(device, 0);} // concept class Shape ... {private: typedef Shape object; template <class T> struct ctable ...{ typedef T* (T::*tcloneT)() const; typedef void (T::*tdeleteT)(); typedef void (T::*tdraw)(monitor device) const; typedef void (*tglobal_drawShape)(const T &refShape, monitor device); tcloneT pcloneT; tdeleteT pdeleteT; tdraw pdraw; tglobal_drawShape pglobal_drawShape; ctable() : pcloneT(reinterpret_cast<tcloneT>(&ctable::cloneT)), pdeleteT(reinterpret_cast<tdeleteT>(&ctable::deleteT)), pdraw(&T::draw), pglobal_drawShape(&::drawShape) ...{} static ctable* vtable() ...{ static ctable static_table; return &static_table; } T *cloneT() const ...{ return new T(*reinterpret_cast<const T*>(this)); } void deleteT() ...{ delete reinterpret_cast<T*>(this); } }; object *pointer; ctable<object> *ptable; object *cloneT() const ...{ return (pointer->*ptable->pcloneT)(); } void deleteT() ...{ (pointer->*ptable->pdeleteT)(); }public: void draw(monitor device) const ...{ (pointer->*ptable->pdraw)(device); } static void drawShape(const Shape &refShape, monitor device) ...{ (*refShape.ptable->pglobal_drawShape)(*refShape.pointer, device); } template <class T> Shape(const T& t) : pointer(reinterpret_cast<object *>(new T(t))), ptable(reinterpret_cast<ctable<object>*>(ctable<T>::vtable())) ...{} Shape(const Shape& rhs) : pointer(rhs.cloneT()), ptable(rhs.ptable) ...{} Shape& operator = (const Shape& rhs) ...{ Shape tShape(rhs); swap(tShape); return *this; } void swap(Shape& rhs) ...{ std::swap(pointer, rhs.pointer); std::swap(ptable, rhs.ptable); } ~Shape() ...{ deleteT(); }} ; void DrawShapes(monitor device, std::vector < Shape > const & g) ... { std::vector<Shape>::const_iterator b(g.begin()), e(g.end()); for(; b != e; ++b) ...{ b->draw(device); Shape::drawShape(*b, device); }} int main( int argc, char * argv[]) ... { std::vector<Shape> vg; vg.push_back(Rectangle()); vg.push_back(Ellipse()); vg.push_back(vg[0]); vg.push_back(vg[2]); vg[3] = vg[1]; //vg.push_back(Triangle()); //错误,不符合Shape concept //vg.push_back(std::string("xxx")); //错误,不符合Shape concept DrawShapes(stdout, vg); return 0;}