I know how to create a single interface that can be applied to different objects. That's not what I'm looking for. I want the opposite behavior: I want to find a mechanism to provide different interfaces to the same object, without paying for virtual calls.
Essentially, lets say I have a queue, with the methods PushMessage, PopMessage and IsEmpty:
class Queue
{
public:
void PushMessage(Message message);
Message PopMessage();
bool IsEmpty() const;
}
I want to hand someone a handle to this queue, but only let them call PopMessage and IsEmpty, and hand someone else a handle to the same queue that only lets them call PushMessage. So the owner of the queue decides who can write to it and who can remove messages from it.
One idea I had was to create two classes that hold no data members of their own, but inherit from Queue and provide proxy methods:
struct EnQueueer
: private Queue
{
void PushMessage(Message message){Queue::PushMessage(message);}
}
struct DeQueueer
: private Queue
{
Message PopMessage(){ return Queue::PopMessage();}
bool IsEmpty() const{ return Queue::IsEmpty();}
}
But I'm not sure this is safe. The owner of the original Queue would have to upcast to EnQueueer or DeQueueer, which I'm not sure is entirely correct. Moreover, the compiler didn't like it:
static_cast<DeQueueer*>(&m_queue); // Results in compile error:
// 'Queue' is an inaccessible base of 'DeQueueer'
reinterpret_cast solves the problem, but I'm not sure if it's safe. Is it safe only as long as the derived classes have no members of their own?