Runtime Concept 的模拟(1)

来源:互联网 发布:我国电力系统分析软件 编辑:程序博客网 时间:2024/05/16 15:25
 
/*
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;
}

原创粉丝点击