Как перегрузить операторы для вызова функции сеттера при вызове operator []? - PullRequest
0 голосов
/ 21 января 2019

Как я могу перегрузить операторы класса, чтобы использовать синтаксис

classInstance[index] = value;

выполняет * * 1004

classInstance.cfgfile.Write(index,value)

справочная информация; не стесняйтесь пропустить.

Приложение, которое мы разрабатываем, использует отображенный в память доступ к сегменту NVRAM - фактически, отображенные - это всего лишь два регистра, адрес и данные. Вы пишете в адресный регистр, затем либо пишете, либо читаете регистр данных. После инициализации чтение и запись выполняются простой перегрузкой [] класса, содержащего ссылку на сегмент памяти. Вы ссылаетесь на экземпляр [], дающий пространство имен по индексу ячейки, которую вы хотите прочитать и записать, и он делает свое дело.

int& IndirectMemory::operator[](RTCMemIndex idx)
{
    *midx_reg = idx;
    return *mdata_reg;
}

(код лишен нерелевантных элементов, таких как мьютексы и проверки работоспособности).

Все работает нормально ... до тех пор, пока NVRAM работает нормально. Этот конкретный чип снят с производства, а те, что «в дикой природе», в настоящее время начали умирать от старости. Их функциональность не имеет большого значения для нашего использования, и мы могли бы перенести их роль на флэш-память практически без последствий (чуть больше износа флэш-памяти), если чип испортится. Дело в том, что мы хотим использовать флэш-запись, используя наш формат конфигурации, который использует геттеры и сеттеры.

int TCfgFile::ReadKey(std::string Key);
void TCfgFile::WriteKey(std::string Key,int data);

И во многих местах кода мы обращаемся к NVRAM посредством IndirectMemory[Some_Register] = Some_Value; записи различных вещей, которые часто меняются, и мы хотим сохранить их после перезагрузки. Я хотел бы сохранить этот синтаксис и поведение, но иметь возможность записи в файл, если обнаружено, что NVRAM поврежден или отключен вручную через запись конфигурации.


Сеть изобилует примерами использования оператора [] для установки заданного значения, просто возвращая ссылку на него. Для пример :

unsigned long operator [](int i) const    {return registers[i];}
unsigned long & operator [](int i) {return registers[i];}

В этом случае, если я позвоню, скажем, reg[3] = 1;, [] вернет ссылку на элемент # 3 и по умолчанию operator= запишет ссылку просто отлично.

Но так как я не могу вернуть ссылку на ключ в файле (.WriteKey() просто выполняет полную запись, возвращая успех или ошибку), а operator= не берет индекс, боюсь, это простой вариант не поможет.

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Вы также можете сделать это без прокси-класса. Вы можете заставить operator[] возвращать ссылку на *this, а затем перегрузить оператор = указанного класса для выполнения Write над тем, что было дано operator= во втором аргументе.

#include <iostream>

struct Foo {
    void Write(int idx, int value) {
        std::cout << "Write(" << idx << ", " << value << ")\n";
    }

    Foo& operator[](int idx) {
        this->index = idx;
        return *this;
    }
    void operator=(int value) {
        this->Write(this->index, value);
    }

    int index;
};

int main() {
    Foo f;
    f[5] = 10;
}

Отпечатки: Write(5, 10)

0 голосов
/ 21 января 2019

Вы можете использовать прокси-класс для решения этой проблемы. Поскольку value нельзя передать в classInstance, нам нужно создать объект, который operator[] может вернуть, который получит значение value и знает, к какому экземпляру применить операцию. Использование

struct Proxy
{
    classInstance_type& to_apply;
    index_type index;
    Proxy(classInstance_type& to_apply, index_type index) : to_apply(to_apply), index(index) {}
    Proxy& operator=(value_type const & value)
    {
        to_apply.cfgfile.Write(index,value)
        return *this;
    }
};

ваш класс operator[] будет выглядеть как

Proxy operator[](index_type index)
{
    return Proxy{*this, index};
}

, а затем, когда вы делаете classInstance[index] = value;, вы вызываете Proxy 'operator=, в котором есть ссылка на вызываемый объект, используемый индекс и значение, которое вам также необходимо.

...