Question

I have two implemented classes:

class DCCmd :
    public DCMessage

class DCReply :
    public DCMessage

Both are protocol messages that are sent and received both ways.

Now in the protocol implementation I'd need to make a message queue, but with DCMessage being abstract it won't let me do something like this:

class DCMsgQueue{
private:
    vector<DCMessage> queue;
public:
    DCMsgQueue(void);
    ~DCMsgQueue(void);

    bool isEmpty();
    void add(DCMessage &msg);
    bool deleteById(unsigned short seqNum);
    bool getById(unsigned short seqNum, DCMessage &msg);
};

The problem is that, as the compiler puts it, "DCMessage cannot be instantiated", since it has a pure abstract method:

virtual BYTE *getParams()=0;

Removing the =0 and putting empty curly braces in DCMessage.cpp fixes the problem, but it is just a hack.

The other solution is that I should make two DCMsgQueues: DCCmdQueue and DCReplyQueue, but this is just duplicated code for something trivial. Any ideas? =)

Was it helpful?

Solution

You cannot instantiate the object because it is abstract as you said. You can however hold a vector of pointers to the DCMessage class which will work, you just need to add the memory address and not the object when pushing it on to the list.

vector<DCMessage*> queue;

DCCmd* commandObject = new DCCmd(...params...);
queue.push_back(commandObject);

BYTE* params = queue[0]->getParams();

OTHER TIPS

You want a vector of DCMessage pointers:

vector<DCMessage*> messages;
messages.push_back(new DCCmd(blah));

Polymorphism in C++ only works through pointers and references, and you can't use references for this. So, pointers it is.

(Voted Kelix up, but I think this needs more elaboration)

What you are looking to do is create a vector of elements that can be of any object derived from your abstract class, right? When you say vector <DCMessage>, you are instead asking for a vector of elements of class DCMessage. You can't have them, as that is an abstract class.

If you instead ask for vector <DCMessage *>, then you can supply pointers to objects of any class derived from DCMessage, and will get dynamic (runtime) dispatch to the correct implementation of your abstract routines when invoked at runtime.

If you want polymorphism, you need pointers in C++, so would use a deque of pointers to the abstract type ( assuming it's a FIFO queue rather than a LIFO ). You then have the problem of managing who owns the messages in the queue.

However, C++ isn't just about OO, and there are idioms in C++ for writing objects to streams; if the message queue just forwards them to a tcp port or has a behaviour similar to , you might want to use those idioms and copy the data rather than storing a reference to the object. If you're implementing techniques to marshall your message objects to and from binary anyway, you might end up saving yourself some bother if your queue is just a buffered stream.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top