tags:

views:

94

answers:

4

How to Define or Implement C# Property in ISO C++ ?

Assume following C# code :

int _id;

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

I know C# convert the get and set lines to getXXX and setXXX methods in compile time. in C++ , programmers usually define these two function manually like :

int _id;

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

but, I want to have the C# syntax or a stuff like it in order to have a simple usability. In C#, we can use properties like :

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

In C++, we can use our function like :

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

Now tell me how can I implement the C# properties in ISO C++.

thanks.

+1  A: 

Short answer: you can't.

Long answer: You could try to simulate them via proxy classes, but believe me this is not worth the minor incovenience in having set/get functions.

You'd have basically to define a class which forwards all the behavior of the variable. This is insanely hard to get right, and impossible to be made generic.

Alexandre C.
+1  A: 

Quite simply. I'd argue this even has no overhead compared to making the variable public. However, you can't modify this any further. Unless, of course, you add two more template parameters that are call backs to functions to call when getting and setting.

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;
    }
};

EDIT: Don't make the call back functions template parameters, just data members that are constant and must be initialized in the constructor for the property. This inherently has greater overhead than simply writing a get and set method your self, because you're making function calls inside of your gets and sets this way. The callbacks will be set at run-time, not compile-time.

Sion Sheevok
This works, as a C# property has no l-value semantics either. For instance, you can't do obj.Property += 5.
Dave Van den Eynde
I would make the "getter" return a const reference, though.
Dave Van den Eynde
@Dave: You can use `+=` on a property in C# quite fine.
Matti Virkkunen
You're right. But you can't pass a property as a reference or output parameter.
Dave Van den Eynde
+3  A: 

As Alexandre C. has already stated, it's very awkward and not really worth it, but to give an example of how you might do it.

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);
        }
};

In your class where you wish to use it, you create a new field for the property, and you must call Init to pass your get/set methods to the property. (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);
    }
};
Mark H
You know, I would pass those member function pointers by template, but that's just me.
DeadMG
I found that your solution is better ! thanks.
Behrouz Mohamadi
+1  A: 

This guy has created a great implementation, fully generic, zero overhead:

http://xinutec.org/~pippijn/en/programming_cpp_properties.xhtml

However, never ever use it in production code because it's confusing to people who have to read it.

Stefan Monov
Excellent solution , Thanks my friend .
Behrouz Mohamadi