Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Structures with different members - decided at runtime

I have the following situation. A pseudo-code is attached below. I have a class A which has an object c of type D or E and this varies (actually its randomly decided). It uses b as a message for communication with a remote computer.

  1. So, how should I get the struct B to have different variables (float or double in this case)?
  2. Also, when I open a socket and transmit an object, the object will now have varying size. The remote computer does not have any idea whether the object has a size corresponding to sizeof(int) + sizeof(float) OR sizeof(int) + sizeof(double). I need the size as a parameter to receive the packets, so how can I solve this?

Code:

class C 
{
  ...
};

class D: public C
{
  ...
};

class E: public C
{
  ...
};

struct B
{
  int a;
  // If A->c is of type D
  float b;
  // If A->c is of type E
  double b;
};

class A
{
  B b;
  C *c;
  A()
  {
    c = (C*) new D;
    //c = (C*) new E;
  }
  ...
  ...
  void transmit()
  {
    //b has some attributes depending on whether c is of type D or E
    //Open a socket and send packets via UDP
    //The remote host receives the packets
  }
};

I hope this explains my problem. If it is not clear or ambiguous, please let me know. I will provide more details and explanation. Thanks in advance.

like image 786
Neel Mehta Avatar asked Jun 06 '11 17:06

Neel Mehta


2 Answers

Either use a factory pattern to create the objects at runtime.

Or, use a template:

template <class T>
class A {
   T a;
}


A<int> a = new A<int>();
A<double> b = new A<double>();

Second part is easy.
In your send-receive protocol keep 4 bytes at the beginning for sizeof (int) ... Then fill it with sizeof(a)

like image 166
Yochai Timmer Avatar answered Sep 21 '22 13:09

Yochai Timmer


Since both D and E derive from C your implementation looks correct:

c = (C*) new D;

Though I would remove the C-Cast (it is not required, if you need casts you should use the C++ variants).

c = new D;

How you transmit the data will depend. But usually you will need to prefix that part of the information with type information so the destination understands how to decode the following stream.

send(a->a);
send("1") if a->c is D
send("2") if a->c is E
send(<Conditional Part>);

As a side note. Look up smart pointers. Using a raw pointer in your class is a bad idea (and not good C++).

like image 26
Martin York Avatar answered Sep 25 '22 13:09

Martin York