Runtime Concept 的模拟(2)

/*
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 (0static void (T::*pdraw)(monitor) const = &T::draw;
            reinterpret_cast
<T*>(pointer)->draw(device);
        }

        
void global_drawShape(void *pointer, monitor device) const
        
{
            
if (0static 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;
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值