一段写晕掉的代码

// 代码重新格式化于20110717

/**
 *  prop.h
 */

#include <malloc.h>

#define CONCAT_DIRECT(a,b)  a##b
#define CONCAT(a,b)         CONCAT_DIRECT(a,b)
#define TOSTR_DIRECT(tag)   #tag
#define TOSTR(tag)          TOSTR_DIRECT(tag)

template <class Owner> struct Property
	{
    Owner *GetOwner(int ofs = -1)
        {
        static int offset = 0;
        if (ofs != -1) offset = ofs;
        return (Owner*)((char*)this - offset);
        }
	};

#define _PROPERTIES_BEGIN(prop_owner)                                                   /
    typedef prop_owner _PropOwner;                                                      /
    struct PropertyWatcher : Property<_PropOwner>                                       /
        {                                                                               /
        PropertyWatcher()                                                               /
            {                                                                           /
            InitProperties(this);                                                       /
            }                                                                           /
        } PropWatcher;                                                                     

#define _PROPERTIES_END(last_prop)                                                      /
    static void InitProperties(Property<_PropOwner> *pCaller)                           /
        {                                                                               /
        /* 20060216, run only once for one type */
        static bool bInited = false;                                                    /
        if (bInited) return;                                                            /
        bInited = true;                                                                 /
       
        PropOwner *pOwner = (_PropOwner *)alloca(sizeof(_PropOwner));                   /
        int offset  = (int)&(pOwner->PropWatcher) - (int)pOwner;                        /
        int num = (int)&pOwner->last_prop - (int)&pOwner->PropWatcher;                  /
        num /= sizeof(Property<_PropOwner>);                                            /
        Property<_PropOwner> *p, *pEnd = pCaller + num;                                 /
        for ( p = pCaller + 1; p <= pEnd; ++p)                                          /
            p->GetOwner(offset += sizeof(Property<_PropOwner>));                        /
        }                                                                                  

#define _PROPERTY(val_type, prop_name, set_proc, get_proc)                              /
    public: struct CONCAT(Prop_, prop_name) : public Property<_PropOwner>               /
        {                                                                               /
        val_type operator = (val_type val)                                              /
            {                                                                           /
            GetOwner()->set_proc(val);                                                  /
            return val;                                                                 /
            }                                                                           /
        operator val_type()                                                             /
            {                                                                           /
            return GetOwner()->get_proc();                                              /
            }                                                                           /
        } prop_name;                                                                           

#define _VIRTUAL_PROPERTY(val_type, prop_name, set_proc, get_proc)                      /
    public: struct CONCAT(Prop_, prop_name) : public Property<_PropOwner>               /
        {                                                                               /
        val_type operator = (val_type val)                                              /
            {                                                                           /
            GetOwner()->CONCAT(VrtlPropSet_, prop_name)(val);                           /
            return val;                                                                 /
            }                                                                           /
        operator val_type()                                                             /
            {                                                                           /
            return GetOwner()->CONCAT(VrtlPropGet_, prop_name)();                       /
            }                                                                           /
        } prop_name;                                                                    /
    virtual void CONCAT(VrtlPropSet_, prop_name)(val_type val) { set_proc(val); }       /
    virtual val_type CONCAT(VrtlPropGet_, prop_name)() { return get_proc(); }                      

#define _VIRTUAL_PROPERTY_OVERRIDE(val_type, prop_name, set_proc, get_proc)             /
    virtual void CONCAT(VrtlPropSet_, prop_name)(val_type val) { set_proc(val); }       /
    virtual val_type CONCAT(VrtlPropGet_, prop_name)() { return get_proc(); }


/**
 *  TestProperty.cpp
 */

class A
    {
    public:
        A() {} 

    int get_a()
        {
        return a;
        }
    void set_a(int v) { a = v; }

    bool get_b()
        {
        return b;
        }
    void set_b(bool v) { b = v; }

    char get_c() 
        { 
        return c; 
        }
    void set_c(char v) { c = v; }

    double get_d() 
        {
        return d; 
        }
    void set_d(double v) { d = v; }

    _PROPERTIES_BEGIN(A)
    _PROPERTY(int, Alpha, set_a, get_a)
    _PROPERTY(bool, Betta, set_b, get_b)
    _PROPERTY(char, Colomb, set_c, get_c)
    _VIRTUAL_PROPERTY(double, Decca, set_d, get_d)
    _PROPERTIES_END(Decca)

    private:
        int     a;
        bool    b;
        char    c;
        double  d;

    };


class B : public A
    {
    public:
        B()
            {
            }

        _VIRTUAL_PROPERTY_OVERRIDE(double, Decca, set_y, get_y);

        void set_y(double v)
            {
            y = v;
            }

        double get_y()
            {
            return y;
            }

    private:
        double y;

    };

int main ()
    {
    B foo;

    cout << "sizeof(A) = " << sizeof(A) << endl;
    cout << "sizeof(B) = " << sizeof(B) << endl;

    foo.Alpha = 13;
    foo.Betta = true;
    foo.Colomb = 'H';
    foo.Decca = 134.56;
    foo.set_d(102.3);

    B another;
    another.Alpha = 125;
    another.Betta = false;
    another.Colomb = 'x';
    another.Decca = 256.34;

    cout << "Alpha: " << foo.Alpha << endl;
    cout << "Betta: " << foo.Betta << endl;
    cout << "Colomb: " << foo.Colomb << endl;
    cout << "Decca: " << foo.Decca << endl;

    A *p = &foo;
    cout << "Virtual Decca:" << p->Decca << endl;
    foo.set_y(45.6);
    cout << "Virtual Decca:" << p->Decca << endl;


    cout << "Alpha: " << another.Alpha << endl;
    cout << "Betta: " << another.Betta << endl;
    cout << "Colomb: " << another.Colomb << endl;
    cout << "Decca: " << another.Decca << endl;

    return 0;
    }

posted @ 2006-02-15 10:24  quanben  阅读(189)  评论(0编辑  收藏  举报