• c++ 属性(转)


    c++ 属性

    来源:http://www.cnblogs.com/ajaxren/archive/2009/08/26/1529934.html

    - -最近非常怀念c++的属性 上网一搜结果 哎不支持,只能用c++进行扩展汗死死死
    “__declspec”是Microsoft c++中专用的关键字,它配合着一些属性可以对标准C++进行扩充。这些属性有:
    align、allocate、deprecated、dllexport、dllimport、 naked、noinline、noreturn、nothrow、novtable、selectany、thread、property和uuid。

    template <class T1, class T2> class KeyValuePair
    {
        
    private:

     
    //-- 参数
     T1  *Key;

     
    //------值
     T2 *Value;
     
    public
         :
     KeyValuePair()
     {
        Key
    =new T1;
        Value
    =new T2;
     }
     
    ~KeyValuePair()
     {
        delete Key;
        delete Value;
     }

    public :
            T1 GetKey()
     {
        
    return this->Key;
     }
     T1 SetKey(T1 inputKey)
     {
        
    this->Key=inputKey;
     }

    private :
        
    int m_old;

    public:
        
    //---------属性----get--------set--------返回数据---属性名称
        _declspec(property(get=GetOld,put=SetOld))int Old; 

      
    int GetOld(void)
       {
        
    return m_old;
       }

       
    void SetOld(int value)
       {
       
          m_old
    =value;
       }
    };

    int main(int argc, char* argv[])
    {
    KeyValuePair
    <int,int> c1;

    c1.Old
    =123;
    cout
    <<c1.Old;
    }

    给C++添加属性机制 

      

    来源:http://blog.csdn.net/pankun/archive/2006/02/08/594274.aspx

        以前用DELPHI和C#时,对DELPHI和C#语法中的属性感到十分方便,在读写属性时能自动调用属性的get, set函数或代码.但我最喜欢的C++中没有属性机制.不过C++提供了范型编程和操作符重载机制,足以让一切变成可能.
        假定要添加属性的类是目标类,给C++添加属性机制,我的想法是建立一个类,重载此类的 "=" 操作符,这样给这个类赋值时,会调用此类的operator = 函数,在此函数中调用目标类的类成员函数即可.但要调用目标类的类成员函数,需要目标类类指针和类成员函数指针.类成员函数指针的类型可以通过模板传入.废话不多说,代码如下:(VC7中编译通过,GCC还未测试)


    Property.h

        /* 
      by 剑神一笑
      属性定义单元
    */

    #ifndef PROPERTY_H
    #define PROPERTY_H


    //辅助类,用来定义类成员函数指针类型
    template<typename T, typename U>
    class PropertyType
    {
    public:
        //指向类成员函数的指针类型
        typedef void (U::*SetProc)(const T&);
        typedef const T& (U::*GetProc)();        
    };

    //属性基类
    template<typename U>
    class PropertyBase
    {
    protected:
        //拥有这个属性的类的指针
        U* obj_;
    public:
        void SetObj(U *obj) 
        {
            this->obj_ = obj;
        }
    };

    //只写属性过程定义
    template<typename T, typename U, typename PropertyType<T, U>::SetProc Set>
    class WriteProperty: public PropertyBase<U>
    {
    protected:
        //定义属性set的函数指针
        typename PropertyType<T, U>::SetProc SetValue;
    public:
        WriteProperty()
        {
            this->SetValue = Set;
        }

        void operator= (const T &value) const
        {
            (obj_->*SetValue)(value);
        }
    };

    //只读属性过程定义
    template<typename T, typename U, typename PropertyType<T, U>::GetProc Get>
    class ReadProperty: public PropertyBase<U>
    {
    private:
        //避免让只读属性可写
        void operator= (const T&) {}
        void operator= (const ReadProperty<T, U, Get>&) {}
    protected:
        //定义属性get的函数指针
        typename PropertyType<T, U>::GetProc GetValue;
    public:
        ReadProperty()
        {
            this->GetValue = Get;
        }

        operator T() const
        {
            return (obj_->*GetValue)();
        }
    };

    template<typename T, typename U, typename PropertyType<T, U>::GetProc Get>
    std::ostream& operator << (std::ostream &out, const ReadProperty<T, U, Get>& rv) 
    {
        out << rv.operator T();
        return out;
    }

    //读写属性过程定义
    template<typename T, typename U, typename PropertyType<T, U>::SetProc Set, typename PropertyType<T, U>::GetProc Get>
    class ReadWriteProperty: public PropertyBase<U>
    {
    private:
        typename PropertyType<T, U>::SetProc SetValue;
        typename PropertyType<T, U>::GetProc GetValue;

        //禁用赋值和拷贝构造
        const ReadWriteProperty<T, U, Set, Get>& operator= (const ReadWriteProperty<T, U, Set, Get>&) {}
        ReadWriteProperty(ReadWriteProperty<T, U, Set, Get>&) {}
    public:
        ReadWriteProperty()
        {
            SetValue = Set;
            GetValue = Get;
        }

        const ReadWriteProperty<T, U, Set, Get>& operator= (const T &value) const
        {
            (obj_->*SetValue)(value);
            return *this;
        }

        operator T() const
        {
            return (obj_->*GetValue)();
        }
    };

    template<typename T, typename U, typename PropertyType<T, U>::SetProc Set, typename PropertyType<T, U>::GetProc Get>
    std::ostream& operator << (std::ostream &out, const ReadWriteProperty<T, U, Set, Get>& rv) 
    {
        out << rv.operator T();
        return out;
    }

    //简化函性定义的宏
    //定义读写属性
    #define PROPERTY_DECLARE_RW(property_name, type, class_type, set, get) \
        ReadWriteProperty<type, class_type, class_type::set, class_type::get> property_name;
    //定义只读属性
    #define PROPERTY_DECLARE_R(property_name, type, class_type, get) \
        ReadProperty<type, class_type, class_type::get> property_name;
    //定义只写属性
    #define PROPERTY_DECLARE_W(property_name, type, class_type, set) \
        WriteProperty<type, class_type, class_type::set> property_name;

    #define INIT_PROPERTY(property_name) property_name.SetObj(this);

    #endif//PROPERTY_H

    //-------------------------华丽的分隔线-----------------------------

    测试代码

    #include <iostream>
    #include <string>
    #include "Property.h"

    using std::cin;
    using std::cout;
    using std::string;

    class Test
    {
    private:
        int value_;
        string name_;
    public:
        Test(int value) 
        {
            INIT_PROPERTY(Value);
            INIT_PROPERTY(Name);
            INIT_PROPERTY(WValue);

            this->value_ = value;
            name_ = "TestClass";
        }

        void SetValue(const int& value) 
        {
            cout << "Set Value: " << value << std::endl;
            this->value_ = value;
        }

        const int& GetValue() 
        {
            cout << "Get Value: " << value_ << std::endl;
            return value_;
        }

        const string& GetName() 
        {
            return name_;
        }

        void ShowValue()
        {
            cout << "Value: " << value_ << std::endl;
        }

        //声明可读写属性,参数为: 属性名,属性类型,当前类名,Set函数,Get函数
        PROPERTY_DECLARE_RW(Value, int, Test, SetValue, GetValue);
        PROPERTY_DECLARE_R(Name, string, Test, GetName);
        PROPERTY_DECLARE_W(WValue, int , Test, SetValue);
    };


    int main() 
    {
        Test t(100);
        t.ShowValue();
        t.WValue = 999;            //只写属性可以写入
        //int i = t.WValue;        //只读属性无法读取
        t.Value = 200;            //读写属性可以写入
        int i = t.Value;        //读写属性可以读取
        cout << "i: " << i << std::endl;
        cout << t.Name << std::endl; //只读属性可以读取
        //t.Name = "hello";        //只写属性无法写入
     
        cin.get();
        return 0;
    }

    运行结果:
    Value: 100
    Set Value: 999
    Set Value: 200
    Get Value: 200
    i: 200
    TestClass

    这种方法是类型安全的,但会让目标类占用更多内存,而且属性调用的函数必须为public的,另外为了让属性类能正确的取得目标类类指针,我使用了一个INIT_PROPERTY宏,这样比较麻烦,需要在构造函数中对每个属性调用一下,希望有更好办法的朋友告知.

    C++类成员属性的一种简洁实现

    作者:佚名 来源:本站整理 发布时间:2008-12-17 22:18:23

        一般来说对于标准C++而言是不存在成员属性这个概念的,以前大家都是用GetXXX/SetXXX来访问或取得数据,好象也没有感觉到任何不便。但是当我们用过C#之类的语言之后,我们总觉得C++这个方式太老土了。于是我们想去实现“属性”这个C++语言缺乏的要素。事实上网络上有很多人已经做了这部分工作,实现的方法有很多种,一种是用模板,一种是根据特定语言来写的,如VC(指的是Microsoft实现的C++)。但是它们要么很复杂,要么很难记住它的准确用法,嗯我总是喜欢简单的东西,因为太复杂的东东会让我的头脑当机。废话少说,来看看如何实现。

        在实现之前,我必需先探讨一下为什么需要“属性”这个东东。比如说下面雇员这个类:

     class CEmployee
    {
    public:
    int Old; //年龄
    };
    CEmployee employee;
    employee.Old=22;
    int old =employee.Old;

     

        它有一个成员变量,我们可以直接对它们进行赋值或者读取,但是往往会缺少一个很重要的东东,就是不能对所赋值进行校验,这可是个大问题,比如我们给Old一个负值,比如-50,程序运行时不会有任何错误,但是的确这个成员变量的值在逻辑上是不正确的。于是我们会写上GetOld、SetOld.现在OK了,这个小问题解决了,但新问题来了。我们的类使用者,他们需要重新把他们的代码成写如下的样子,而不是上面的那样。

     CEmployee employee;
    employee.SetOld(22);
    int old =employee.GetOld();

        你的伙伴一定会在写代码时诅咒你写了一个垃圾的类。所以你决定要改变这个现状。很幸运,你是MS的忠实用户,而且你对于MSDN看很仔细,所以你知道可以这样来写

     class CEmployee
    {
    private:
    int m_old;
    public:
    _declspec(property(get= GetOld,put=SetOld))int Old;

    int GetOld(void)
    {
    return m_old;
    }
    void SetOld(int value)
    {
    if( (value >0) && (value <60))
    {
    m_old = value;
    }
    else
    {
    m_old =20;
    }
    }
    };

        Very Good,上面的类完美地完成一个属性所要做的目标,不过还有一点小问题,象我这样比较笨的经常需要查找MSDN才会知道_declspec(property(get= GetOld,put=SetOld))int Old;这句话的含义,而且我也经常忘记它的具体写法,比如put我常把它写成了set,这总是让我想起了使用C#的美好时光,它是可以写成这个样子的

     public class CEmployee
    {
    private int m_old;
    public int Old
    {
    get
    { return m_old; }
    set
    {
    if(value >0 && value <60)
    {
    m_old = value;
    }
    else
    {
    m_old =20;
    }
    }
    }
    }

        所以我想到可以利用C/C++中强大的武器宏,我们来定义几个宏

     #define PROP(T,X) __declspec(property(get= __get##X,put= __put##X))T X;
    #define GETPROP(T,X) __declspec(property(get= __get##X))T X; //只读属性
    #define SETPROP(T,X) __declspec(property(put= __put##X))T X; //只写属必
    #define GET(T,X) T __get##X(void)
    #define SET(T,X) void __put##X(T value)

        说明一下:T 代表属性的类型如int,double,CString,而X代表属性名称。如果你需要一个只读属性可以使用GETPROP,只写属性则可以使用SETPORP,然后对应使用一个GET或SET,当然如果你用PROP,而只用了一个GET或SET,也没有错,只是在编译时会告诉你没有一个__getXXX或__putXXX的方法。然后我们就可以这样来写我们的类。

     class CEmployee
    {
    private:
    int m_old;
    public:
    PROP(int ,Old)
    GET(int,Old)
    {
    return m_old;
    }
    SET(int,Old)
    {
    if( (value >0) && (value <60)) //这里的value你可把它和C#一样当做关键字
    {
    m_old = value;
    }
    else
    {
    m_old =20;
    }
    }
    };

        好了,我们要做的工作已经做完了。当然这种方法还是有很多问题,比如不能使用C#中常用的索引属性,静态属性等等。但是毕竟我们是C++程序员么,呵呵!最后,这种方法只是在VC下有用。

  • 相关阅读:
    list浅析
    C#尝试读取或写入受保护的内存。这通常指示其他内存已损坏(catch不起作用)
    浅析C#线程同步事件-WaitHandle
    C#操作xml方法1
    C#简单的操作csv文件
    C#的int类型?,??,~的意思,string类型空值赋值
    将多个exc表格汇总于一个表格中
    C#禁止双击标题栏等操作
    c#泛型
    c#session
  • 原文地址:https://www.cnblogs.com/dabaopku/p/1698330.html
Copyright © 2020-2023  润新知