Как реализовать чтение и запись информации в классе разными способами?

124
28 мая 2021, 15:00

В Delphi для чтения и записи свойств можно использовать разные функции. Это для примера. В С++ при вызове функции pNext() (r-value) нужно получить содержимое поля класса. А если функция вызывается слева от знака присваивания (l-value), то нужно изменить содержимое поля. То есть поведение переменной по умолчанию. Поле частное и напрямую недоступно. Пробовал использовать возврат ссылки, но ругается на переопределение функции. То есть нужно разделить левый и правый вызов функции.

using size_t = long unsigned int;
template<typename T>
class CQueue {
  public:
    CQueue() {
      xInit();
    }
    CQueue & xInit(){
      pQueuePrev=nullptr;
      pQueueNext=nullptr;
      ulHash=ulHashCalc();
      return *this;
    }
    void vInsertTo(CQueue & pWhere){
      if(ulHashCalc() == this->ulHash ){
        this->ulHash = pWhere.ulHash;
        this->pQueuePrev = &pWhere;
        pWhere.pQueueNext = this;
      }
    }
    void vRemoveMe(){
      if(nullptr!=pQueuePrev){
        pQueuePrev->pQueueNext = pQueueNext;
      }
      if(nullptr!=pQueueNext){
        pQueueNext->pQueuePrev = pQueuePrev;
      }
      pQueueNext = nullptr;
      pQueuePrev = nullptr;
      ulHash = ulHashCalc();
    }
    T * pPrev(){
      return reinterpret_cast<T *>(pQueuePrev);
    };
    T * pNext(){
      return reinterpret_cast<T *>(pQueueNext);
    }
    T & pPrev(){
      return *reinterpret_cast<T *>(pQueuePrev);
    };
    T & pNext(){
      return *reinterpret_cast<T *>(pQueueNext);
    }
  private:
    CQueue * pQueuePrev;
    CQueue * pQueueNext;
    size_t ulHash;
    size_t ulHashCalc(){
      return reinterpret_cast<size_t>(this);
    }
};

Можно, конечно, приватные данные сделать публичными, но не желательно. В функциях можно произвести контроль целостности и прочего. https://godbolt.org/z/LXeDJP

Answer 1

В С++ для реализации доступа к инкапсулированным полям класса используются методы - геттер и сеттер.

В обязанности геттера входит возвращение значения поля (ссылки/указателя/копии), сеттер отвечает за присвоение полю нового значения.

При проектировании класса также играет роль константность таких методов. Метод-геттер обычно делают константным, а сеттер не константным. Тогда геттер можно будет вызывать на константных объектах, а сеттер - нельзя.

class widget
{
    public:
    int get_width() const { return width; }
    void set_width(int value) { width = value; }
    private:
    int width;
}
int main()
{
    widget w {};
    const widget cw {};
    w.set_width(100);       // ok
    int a = cw.get_width(); // ok
    int b = w.get_width();  // ok
    cw.set_width(300);      // ошибка
    // как и должно быть - состояние постоянного объекта поменять нельзя
    // но узнать его состояние - можно
}
READ ALSO
Убрать checked с потомков input[type=checkbox]

Убрать checked с потомков input[type=checkbox]

Как сделать так, чтоб при выборе страны снималось выделение со всех соответствующих городов и наоборот, при выборе города снималось выделение...

348
Как сверстать круговую диаграмму с фоновым изображением?

Как сверстать круговую диаграмму с фоновым изображением?

Внимание! Это дубль вопроса с тостера! Автор не я, просто вопрос показался интересным:

91
Вставка даты по умолчанию на HTML странице

Вставка даты по умолчанию на HTML странице

Для выгрузки операций из БД на html-странице есть 2 окна для ввода периода времени "с" и "по"Если написать в коде страницы: body onload = "ShowMonthDate();", то при...

145