У меня есть базовый класс, Message
, который определяет политику.Я также получил производные этого класса для конкретных экземпляров сообщений.
Рассмотрим этот упрощенный пример:
template< ::size_t MessageSize >
struct Message {
enum { size = MessageSize };
Bits< ChunkSize > bits_[size / ChunkSize];
// Defines behavior for the Message types
};
template< ::size_t MessageSize >
struct SmallMessage : public Message< MessageSize > {
Bits< MessageSize > bits_;
};
// other derivations of Message...
template< class MessageType, ::size_t MessageSize >
struct MakeMessage {
typedef typename IfElseType<
MessageSize < ChunkSize,
SmallMessage< MessageSize >,
Message< MessageSize >
>::type type;
};
Если ChunkSize
равно 32, и я генерирую следующее:
MakeMessage< FooMessage, 16 >
Message< 16 >
приведет к Bits< 32 > bits_[0];
, а SmallMessage< 16 >
будет содержать Bits< 16 > bits_
, который, насколько я понимаю, будет затенять исходный элемент нулевого размера.
Я знаю несколько способов справиться с этим:
- Объявить имя, отличное от
bits_
, и предоставить переопределенный интерфейс для этого - Изменить
SmallMessage
скрыть все методы Message
, которые имеют дело с bits_
с локальными реализациями - Сделать методы в
Message
virtual
Мой вопрос: есть ли пользалибо подходить, либо, если есть лучший способ предоставить интерфейс для контейнеров памяти различного размера, как описано выше.
В конечном счете, я хотел бы иметь что-то вроде:
typedef MakeMessage< FooMessage, 16 >::type message_type;
// ...
message_type message;
message.doSomethingToBits ();
Работайте одинаково, независимо от того, какой контейнер на самом деле используется.