Как определить или реализовать свойство C # в ISO C ++? - PullRequest
0 голосов
/ 18 сентября 2010

Как определить или реализовать свойство C # в ISO 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

Теперь скажите мне, как я могу реализовать свойства C # в ISO C ++.

спасибо.

Ответы [ 3 ]

3 голосов
/ 18 сентября 2010

Как уже говорил Александр С., это очень неловко и на самом деле не стоит, но привести пример того, как вы могли бы это сделать.

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 голос
/ 18 сентября 2010

Довольно просто.Я бы сказал, что это даже не имеет никаких накладных расходов по сравнению с обнародованием переменной.Тем не менее, вы не можете изменить это дальше.Если, конечно, вы не добавите еще два параметра шаблона, которые являются функциями обратного вызова для функций, вызываемых при получении и настройке.

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 самостоятельно, потому что вы делаете вызовы функций внутри ваших get и set таким образом.Обратные вызовы будут установлены во время выполнения, а не во время компиляции.

1 голос
/ 18 сентября 2010

Краткий ответ: вы не можете.

Длинный ответ: Вы можете попытаться смоделировать их через прокси-классы, но, поверьте мне, это не стоит незначительных неудобств при наличии функций set / get.

В основном вам нужно определить класс, который будет перенаправлять все поведение переменной. Это безумно трудно понять правильно и невозможно сделать общим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...