Доступ через прокси

Возможно ли, чтобы класс действовал как прокси при доступе к своим членам? Самым простым способом, конечно, было бы написать методы получения / установки, но это негибко и нелегко, поскольку вы должны написать все установщики самостоятельно, что увеличивает объем кода.

Проблема в том, что я хочу абстрагироваться от того факта, что некоторые данные находятся в программе микроконтроллера. В основном я хочу это

MemberType member = object->member; // won't work if object lies in progmem

переводиться на что-то вроде

MemberType member; // Allocate memory in RAM for the member
memcpy_P(&member,
&object->member, // assuming that this gives a valid pointer to the member
sizeof(MemberType));

Во встроенном C можно использовать адресное пространство __flash сделать что-то подобное. К сожалению, C ++ не поддерживает это.

Вот я и подумал о перегрузке operator->(), к несчастью operator->() не получает никакой информации, к какому участнику вы собираетесь обратиться (кстати: почему wtf? Единственная цель -> — получить доступ к члену, так почему кто-то захочет выбросить эту информацию?). . не может быть отменено вообще.

Кто-нибудь знает, как решить эту проблему? Синтаксис не должен быть -> конечно. Если бы это было возможно с какой-то эзотерической шаблонной конструкцией, я тоже был бы счастлив. Я не знаю достаточно C ++, может быть, это невозможно вообще. C ++ кажется немного негибким на стороне метапрограммирования.

Редактировать: после получения ответа я решил использовать класс-оболочку и переопределить оператор приведения.

template<typename Type>
class InProgmem {
Type const self; // InProgmem<Type> should be as big as Type
InProgmem(Type val) : self(val) {} // Keep the compiler quiet
public:
operator Type() const {
Type out;
memcpy_P(&out, this, sizeof(Type));
return out;
}
} __attribute__((packed));

// Example use:
PROGMEM prog_uchar foo = 14;
class Test {
public:
InProgmem<unsigned char> bar;
};
Test *baz = (Test*)&foo;
unsigned char bar = baz->bar;

0

Решение

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

const MemberType &MemberType::operator=(const ProgmemMemberType &other)
{
memcpy_P(this,
other.progMemPointer(),
sizeof(MemberType));
return *this;
}

const ProgmemMemberType &ProgmemMemberType::operator=(const MemberType &other)
{
// Whatever the reverse of memcpy_P is...
return *this;
}

Тогда вы можете написать MemberType member = object->member или же object->member = member и оператор присваивания сделает всю работу.

Это самое чистое решение, которое я могу придумать; -> Оператор не предназначен для такого рода вещей.

И, конечно, если вы не хотите определять новый класс-оболочку для каждого используемого вами типа, вы можете использовать шаблонный класс.

1

Другие решения

Других решений пока нет …