Возможно ли, чтобы класс действовал как прокси при доступе к своим членам? Самым простым способом, конечно, было бы написать методы получения / установки, но это негибко и нелегко, поскольку вы должны написать все установщики самостоятельно, что увеличивает объем кода.
Проблема в том, что я хочу абстрагироваться от того факта, что некоторые данные находятся в программе микроконтроллера. В основном я хочу это
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;
Вы можете создать новый класс 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
и оператор присваивания сделает всю работу.
Это самое чистое решение, которое я могу придумать; ->
Оператор не предназначен для такого рода вещей.
И, конечно, если вы не хотите определять новый класс-оболочку для каждого используемого вами типа, вы можете использовать шаблонный класс.
Других решений пока нет …