Runtime Concept 的模拟(1)

 
/*
Runtime Concept 的模拟(1)
无意间看到longshanks的blog《OOP的黄昏》
http://www.cppblog.com/longshanks/archive/2007/12/06/37915.html
受益匪浅!
以前没意识到还有Runtime Concept这么好的东东。
一时技痒,就来模拟一个,在C++0x还没出来之前,勉强也可以用用。

基本原理:
在concept类的构造函数里把约束的函数放到函数指针。

这个实现的缺陷:
1. 成员函数的调用方法不知道是不是符合标准,不过估计移植性没什么问题。
2. concept类随着约束的增加而增大。
3. concept类只能引用,这样就不能很好的使用std::vector了。

另:
1. VC的非虚成员函数指针居然可以指向虚函数并正常调用,诡异。
*/


#include 
< stdio.h >
#include 
< vector >
#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:
    
class object{};
    
const object* pointer;
    typedef 
void (object::*tdraw)(monitor device) const;
    typedef 
void (*tglobal_drawShape)(const object& refShape, monitor device);
    tdraw pdraw;
    tglobal_drawShape pglobal_drawShape;
    
public:
    
void draw(monitor device) const
    
{
        (pointer
->*pdraw)(device);
    }

    
static void drawShape(const Shape &refShape, monitor device)
    
{
        (
*refShape.pglobal_drawShape)(*refShape.pointer, device);
    }

    
    template 
<class T>
    Shape(
const T& t) : 
        pointer(reinterpret_cast
<const object*>(&t)), 
        pdraw(reinterpret_cast
<tdraw>(&T::draw)), 
        pglobal_drawShape(reinterpret_cast
<void (*)(const object&, monitor)>
            (static_cast
<void (*)(const T&, monitor)>(&::drawShape)))
    
{
        
if (0static void (T::*tdraw)(monitor) const = &T::draw;
        
if (0static void (*pglobal_drawShape)(const T&, monitor) = &::drawShape;
    }

    
    Shape
& operator = (const Shape& rhs)
    
{
        pointer 
= rhs.pointer;
        pdraw 
= rhs.pdraw;
        pglobal_drawShape 
= rhs.pglobal_drawShape;
        
return *this;
    }

}
;

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[])
{
    Rectangle s1;
    Ellipse s2;
    std::vector
<Shape> vg;
    vg.push_back(s1);
    vg.push_back(s2);
    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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值