We help IT Professionals succeed at work.

Constructing an object with three different member variables

ambuli
ambuli asked
on
Hi Experts,

I have to provide an API to users who need to send some command to the server.
the commands will be of the form
class API
{
   void sendWrite()
   void sendUpdate()
   void sendRead()
   void sendDelete()
};


I need to construct an object with the following which is the command to be send to a server.  The command is of this form(i.e, three separate lines with the following format)
msg:::write
id:::123
data::dataValue

msg is one of  write, read, delete, update, etc.  
id is not relevant for now.
The dataValue may be a string, int or a json encoded string. I will be setting this data field according the command.

I have another class that actually send this string to the server.

bool cmdSender::sendCommand()
{

}

What I am trying to do is to create the commandMsgs and
do something like
sender->sendCommand(cmd.getString());

So, I need to create a Command class and constuct it as per the request.  What is the better way to do it.

class Command
{
       

}

So, I need to create the Command objects by simply passing

Command *cmd = new Command(write, 123, dataValueString);
then call sendCommand(cmd->getString())  or something like this.  
Comment
Watch Question

CERTIFIED EXPERT
Commented:
I think your suggested design is just about right.

For this step:
Command *cmd = new Command(write, 123, dataValueString);
then call sendCommand(cmd->getString())  or something like this.  

You probably want to create specific subclasses of Command for the different types of parameters they take.

E.g. IntCommand : Command {
}
so you can say:
Command *cmd = new IntCommand(write, 1234, intdataValue) ;
sendCommand(cmd->getString()) ;

then IntCommand will know how to generate the command string and how to handle an "int" for its data parameter.

Doug
CERTIFIED EXPERT

Commented:
You might want to look into using a Factory design pattern. Each type of command has its own class, all derived from a base "Command" class - a "Command_factory" class is built which creates objects of the correct type and returns a "Command" pointer. Another design pattern of use could be the Command pattern.

I recently used the Factory and Command design patterns for a web-update application. I found them to be a little extra work than the simple design I originally envisaged, but the benefits were realised as I added new types of commands to my application without changing the application logic. The command logic was encapsulated in the new command classes I was creating.

Cheers,
  Chris
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
You basically need to provide a constructor that takes these three values as it's parameter, e.g.
class Command
{
public:
  enum msg { read, write};

  Command(msg m,int id, const std::string& cmd) : m_msg(msg), m_id(id), m_cmd(cmd) {}

  void sendCommand(cost std::string& str) { /* do it */ }

protected:

  msg m_msg;
  int m_id;
  std::string m_cmd;
};

Open in new window

Senior Software Engineer (Avast)
CERTIFIED EXPERT
Commented:
Your requirement is a little unclear but the way I read it is you want to construct an object with a msg action, an integer id and an arbitrary datum and you want your command class to abstract the conversion to a string that can then be sent. Is that right?

Anyway, assuming that is what you want to do you can use a command class with a templated constructor to do something like that.
#include <string>
#include <sstream>
#include <iostream>

class Command
{
public:
   template <typename T>
   Command(std::string const & msg, int id, T const & tdata)
   {
      std::ostringstream oss;
      oss << msg << "\n" << id << "\n" << tdata << "\n";
      tosend_ = oss.str();
   }

   std::string get() const
   {
      return tosend_;
   }

private:
   std::string tosend_;
};

void send(Command const & cmd)
{
   std::cout << "sending...\n" << cmd.get() << std::endl;
}

int main()
{
   Command cmd1("write", 123, 43523);
   Command cmd2("write", 123, "foobar");
   send(cmd1);
   send(cmd2);
}

Open in new window

Explore More ContentExplore courses, solutions, and other research materials related to this topic.