Я реализую причудливый тип указателя, который оборачивает параллельный контроллер памяти, для чтения и записи по указателю с внешней SDRAM. Требования к использованию несколько следующие:
// High level overview of class definition:
class extern_pointer {
class extern_value; // Used as temporary for *e_ptr = ...; etc.
{...}
};
auto e_ptr = hwstl::extern_pointer<struct_in_external_memory>(...);
// set pointer to point to 0x0010000
// extern_pointer&::operator= (e_ptr::address_type); sets internal ptr value
e_ptr = 0x0010000;
// extern_value&::operator= (e_ptr::char_type);
// note: char_type is the minimum size of addressable set of bits,
// variations for extern_value&::operator= are allowed for wider databusses
*e_ptr = 0x60;
// invokes const extern_pointer&::operator*,
// obtains a copy and implicitly converts to
// struct_in_external_memory
struct_in_external_memory v = *e_ptr;
Теперь, когда я реализовывал operator * для extern_pointer, я понял, что operator-> это тоже вещь.
Для оператора * я мог бы просто вернуть временное значение extern_value, которое перегружает некоторые операторы, чтобы создать ощущение указателя.
Но для -> это не так, поскольку требуется, чтобы extern_value содержала все члены и методы, которые вместо этого ссылаются на внешнюю память.
Есть ли что-нибудь, что я могу сделать, кроме удаления extern_value* operator->()
?
Редактировать:
с объявлением:
class struct_in_external_memory {
void MyMethod() { /* changes some internal stuff */ }
};
По сути, я хочу иметь возможность:
e_ptr->MyMethod()
Обычно MyMethod является членом struct_in_external_memory, но -> должен возвращать ‘extern_value *’ `
Ну в зависимости от struct_in_external_memory
и его сложность, вы все равно можете его реализовать. Последняя ссылка в цепочке звонков на operator->
должен быть необработанным указателем, это неизбежно, но это не значит, что он должен быть необработанным указателем на эту фактическую структуру.
class extern_value_holder {
struct_in_external_memory copy;
public:
extern_value_holder(/*...*/) {
// this should initialize copy to reflect the value in external memory
}
struct_in_external_memory* operator->() && { return © }
~extern_value_holder() {
//Write copy back to external memory
}
};
Здесь возвращаемый указатель на копию объекта, который вы хотите изменить, но не можете. Вызывающий абонент изменяет его, и он автоматически синхронизируется, когда extern_value_holder
достигает конца своего времени жизни в конце полного выражения, содержащего obj->member
,
Что возвращает нас к тому, что я предвосхитил. Это зависит от struct_in_external_memory
насколько дешево это копировать; на это может даже быть скопировано. Если вы хотите поддерживать многопоточные среды, вам нужно добавить синхронизацию сверху.
Который начинает выглядеть как большая работа для очень маленькой выгоды. Это просто один Оператор в конце концов.
Других решений пока нет …