2010-06-28 2 views
3

Я хотел бы создать объект C++ для обертывания ОЗУ внешнего периферийного устройства. Я пытаюсь настроить что-то вроде следующего:Как сопоставить удаленное устройство как массив на C++?

Периферийное p;

p [4] = 10;

int n = p [5];

Для этого мне нужно читать или писать на периферию всякий раз, когда к элементу массива обращаются. Я не могу понять, как это сделать, используя перегрузку оператора и т. Д. Я могу вернуть объект «accessor», который можно использовать как lvalue во второй строке:

PeripheralAccessor Peripheral :: operator [] (int i);

или я могу определить «простой» оператора, который может использоваться для считывания Int из периферийного устройства на третьей линии:

INT Периферийное :: Оператор [] (INT I);

, но я не могу заставить их сосуществовать, чтобы обеспечить доступ как для чтения, так и для записи на периферию. Я могу определить этот второй оператор как оператор const (rvalue), но он ТОЛЬКО будет вызван для экземпляра const класса, которого недостаточно для моих нужд ...

Надеюсь, я объяснил, что Я пытаюсь достичь здесь ясно; может ли кто-нибудь предложить, как я должен это делать (или действительно ли это возможно)?

ответ

3

Обычный способ справиться с этим является использование прокси-объект:

class register_proxy { 
public: 
    register_proxy &operator=(int value) { 
     write_value(value); 
    } 

    operator int() { 
     return read_value(); 
    } 
}; 

class peripheral { 
    register_proxy registers[4]; 
public: 

    register_proxy &operator[](int reg_num) { return registers[reg_num]; } 
}; 

Я оставил некоторые детали (например, как вы говорите каждый register_proxy, что фактический номер регистра для чтения/записи - как правило, передавая аргумент в ctor). В любом случае, общая идея довольно проста: operator[] возвращает ссылку на прокси-объект. Объект прокси operator int (или, что бы он ни делал, конечно) вызывается, когда вы используете его в правой части задания. Объект прокси operator= вызывается, когда он находится в левой части задания, поэтому вы пытаетесь записать там значение.

+0

+1, писал одно и то же. –

+0

@Nikolai такой же здесь. – Cogwheel

+0

Блестящий, спасибо. Это был факт, что вы могли бы сделать: оператор int() , что я не разработал. – Jonny

1

Поскольку вы не можете перегружать по типу возврата, вам нужно выбрать тот или иной (и вы не можете выбрать int, потому что вы не получите поведение lvalue). Однако вы можете предоставить PeripheralAccessor автоматическое преобразование в int.

Редактировать: Джерри избил меня. С кодом даже.

2

Дайте неявный оператор "PeripheralAccessor" Конверсия для междунар:

operator int() const; 
Смежные вопросы