/**/ /*Runtime Concept 的模拟(2)上一篇基本模拟了Runtime Concept,但有些缺陷。改之。基本原理:1. 按concept的约束函数创建一个虚基类,然后在模板<T>的子类里实现函数转发。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: struct ctablebase ...{ virtual void *cloneT(void *pointer) const = 0; virtual void deleteT(void *pointer) const = 0; virtual void draw(void *pointer, monitor device) const = 0; virtual void global_drawShape(void *pointer, monitor device) const = 0; }; template <class T> struct ctable : public ctablebase ...{ static ctablebase* vtable() ...{ static ctable static_table; return &static_table; } void *cloneT(void *pointer) const ...{ return new T(*reinterpret_cast<T*>(pointer)); } void deleteT(void *pointer) const ...{ delete reinterpret_cast<T*>(pointer); } void draw(void *pointer, monitor device) const ...{ if (0) static void (T::*pdraw)(monitor) const = &T::draw; reinterpret_cast<T*>(pointer)->draw(device); } void global_drawShape(void *pointer, monitor device) const ...{ if (0) static void (*pdrawShape)(const T&, monitor) = &::drawShape; ::drawShape(*reinterpret_cast<T*>(pointer), device); } }; void *pointer; ctablebase *ptable;public: void draw(monitor device) const ...{ ptable->draw(pointer, device); } static void drawShape(const Shape &refShape, monitor device) ...{ refShape.ptable->global_drawShape(refShape.pointer, device); } template <class T> Shape(const T& t) : pointer(new T(t)), ptable(ctable<T>::vtable()) ...{} Shape(const Shape& rhs) : pointer(rhs.ptable->cloneT(rhs.pointer)), 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() ...{ ptable->deleteT(pointer); }} ; 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;}