А кому отсыпать свойств С++?

Тема в разделе "Глядите, что я сделал", создана пользователем DetSimen, 6 ноя 2018.

  1. DetSimen

    DetSimen Guest

    Тем, кто как я тоскует по милым свойствам C#, и кто, как и я испытывает идиосинкразию к вызовам getValue() и setValue() для доступа к внутренним, скрытым полям своего класса, предлагается простейшее решение. Для начала определим что такое свойство: это внутреннее поле какого-либо типа со своими функциями установки и чтения, потом формализуем это в шаблоне

    Код (C++):
    template<typename T, typename V>
    class TProperty {

        using PSetterFunc = void (V::*)(T);
        using PGetterFunc = T(V::*)() const;

    private:
        V* const            fobject;
        PSetterFunc const    fsetter;
        PGetterFunc const    fgetter;

    public:

        TProperty(V* AClass, PGetterFunc getFunc , PSetterFunc setFunc)
            :fobject(AClass),fsetter(setFunc),fgetter(getFunc)     {}

        operator T() const
        {
            return (fobject->*fgetter)();
        }

        T operator = (T AValue) {
       
            (fobject->*fsetter)(AValue);
            return AValue;
        }

    };
    и всё. Теперь это можно встраивать в свой класс, типа так

    Код (C++):
    сlass TClass {      // прародитель всех классов в цепочке наследования

    private:
        mutable uint16_t fid=0;   // идентификатор экземпляра класса (в самом простом случае - его адрес в ОЗУ)

        uint16_t getID(void) const {
            if (fid == 0) fid = reinterpret_cast<uint16_t>(this);   // если fid не присвоен, присвоим ему адрес обьекта в памяти
            return fid;                                             // и вернем fid
        }

        void setID(uint16_t avalue) { fid = avalue; };                 // установим свой ID для конкретного экземпляра класса

    protected:

          virtual bool init(void) { return true; };           // это к делу не относица

    public:

        TProperty<uint16_t, TClass> ID{ this,&TClass::getID,&TClass::setID };   // это обьявление свойства ID типа uint16_t
    };
    ну и обращаться потом без всяких скобок

    Код (C++):
    TClass myClass;
    .
    .
    .
    uint16_t myClassID = myClass.ID;
    В применении к Ардуино, я думаю, всё вышенаписанное имеет чисто академический интерес, ибо шаблоны непомерно раздувают код, но тем кто пишет для STM или ESP, мошт будет полезно. Еще, таким образом можно создавать только свойства для чтения/записи, что не всегда полезно, в большинстве задач требуются свойства только для чтения. В качестве костыля, можно просто формально обьявить пустой setter, который не изменяет значение внутреннего поля. Кактатак.
    ЗЫ. Конструктор свойства отрабатывает ДО основного конструктора, поэтому тем, хто как я, любит в конструкторе делать memset(this,0,sizeof(*this)) надлежит крепко наморщить мозг чтоб избежать. Чего? А подумайте.

    Идея: https://stackoverflow.com/questions/8368512/does-c11-have-c-style-properties
     
    Последнее редактирование модератором: 7 ноя 2018
    DIYMan, ИгорьК, Andrey12 и ещё 1-му нравится это.
  2. parovoZZ

    parovoZZ Гуру

    на хрена в МК классы?
     
  3. DetSimen

    DetSimen Guest

    мне нраица
     
  4. сейчас дядя витя придет и расскажет. )
     
  5. parovoZZ

    parovoZZ Гуру

    вата?