如何在ISO C ++中定义或实现C#属性?

时间:2010-09-18 17:38:06

标签: c# c++ properties

如何在ISO C ++中定义或实现C#属性?

假设遵循C#代码:

int _id;

int ID
{
    get { return _id; }
    set { _id = value; }
}

我知道C#在编译时将get和set行转换为getXXX和setXXX方法。在C ++中,程序员通常手动定义这两个函数,如:

int _id;

int getID() { return _id; }
void setID(int newID) { _id = newID; }

但是,我希望拥有C#语法或类似的东西,以便具有简单的可用性。 在C#中,我们可以使用以下属性:

ID = 10;              // calling set function
int CurrentID = ID;   // calling get function

在C ++中,我们可以使用我们的函数:

setID(10);                 // calling set function
int CurrentID = getID();   // calling get function

现在告诉我如何在ISO C ++中实现C#属性。

感谢。

3 个答案:

答案 0 :(得分:3)

正如亚历山大·C已经说过的那样,它非常尴尬而且不值得,但举一个例子说明你可能会这样做。

template <typename TClass, typename TProperty>
class Property
{
    private:
        void (TClass::*m_fp_set)(TProperty value);
        TProperty (TClass::*m_fp_get)();
        TClass * m_class;

        inline TProperty Get(void)
        {
            return (m_class->*m_fp_get)();
        }

        inline void Set(TProperty value)
        {
            (m_class->*m_fp_set)(value);
        }

    public:
        Property()
        {
            m_class = NULL;
            m_fp_set = NULL;
            m_fp_set = NULL;
        }

        void Init(TClass* p_class, TProperty (TClass::*p_fp_get)(void), void (TClass::*p_fp_set)(TProperty))
        {
            m_class = p_class;
            m_fp_set = p_fp_set;
            m_fp_get = p_fp_get;
        }

        inline operator TProperty(void)
        {
            return this->Get();
        }

        inline TProperty operator=(TProperty value)
        {
            this->Set(value);
        }
};

在您希望使用它的类中,为属性创建一个新字段,并且必须调用Init将get / set方法传递给该属性。 (pref in .ctor)。

class MyClass {
private:
    int _id;

    int getID() { return _id; }
    void setID(int newID) { _id = newID; }
public:
    Property<MyClass, int> Id;

    MyClass() {
        Id.Init(this, &MyClass::getID, &MyClass::setID);
    }
};

答案 1 :(得分:1)

简短回答:你不能。

答案很长:您可以尝试通过代理类来模拟它们,但请相信我值得在设置/获取函数时遇到轻微的不便。

你基本上要定义一个转发变量所有行为的类。这很难做到正确,也不可能变得通用。

答案 2 :(得分:1)

很简单。我认为,与变量公开相比,这甚至没有开销。但是,您无法进一步修改此内容。当然,除非您在获取和设置时添加另外两个模板参数,这些参数是要调用的函数的回调。

template<typename TNDataType>
class CProperty
{
public:
    typedef TNDataType TDDataType;
private:
    TDDataType m_Value;
public:
    inline TDDataType& operator=(const TDDataType& Value)
    {
        m_Value = Value;
        return *this;
    }

    inline operator TDDataType&()
    {
        return m_Value;
    }
};

编辑:不要使回调函数模板参数,只是数据成员是常量,必须在属性的构造函数中初始化。这本身就比简单地编写一个get和set方法更有开销,因为你在gets中进行函数调用并以这种方式设置。回调将在运行时设置,而不是在编译时设置。