我有以下情况。下面附有伪代码。我有一个类A,它有一个D或E类型的对象c,这个变化(实际上是随机决定的)。它使用b作为与远程计算机通信的消息。
代码:
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
}
};
我希望这能解释我的问题。如果不清楚或含糊不清,请告诉我。我会提供更多细节和解释。提前谢谢。
答案 0 :(得分:2)
使用 factory pattern 在运行时创建对象。
或者,使用模板:
template <class T>
class A {
T a;
}
A<int> a = new A<int>();
A<double> b = new A<double>();
第二部分很容易。
在你的发送 - 接收协议中,在sizeof(int)的开头保留4个字节......然后用sizeof(a)
填充它
答案 1 :(得分:1)
由于D和E都来自C,因此您的实现看起来是正确的:
c = (C*) new D;
虽然我会删除C-Cast(不需要,如果你需要强制转换,你应该使用C ++变体)。
c = new D;
您如何传输数据取决于。但通常您需要在信息的前面加上类型信息的前缀,以便目的地了解如何解码后续流。
send(a->a);
send("1") if a->c is D
send("2") if a->c is E
send(<Conditional Part>);
作为旁注。查找智能指针。在你的类中使用原始指针是一个坏主意(而不是很好的C ++)。
答案 2 :(得分:1)
使用普通C ++和原始套接字是非常繁忙的,很多人最终通过套接字传递结构而不考虑其他问题因此而上升..
如果您不担心性能,我建议将数据作为XML / ini内容发送,这很容易解析.INI读者可以方便地将参数读取为float或double ..
如果您仍然喜欢二进制内容,我建议您学习ASN.1符号,但至少需要2周时间才能完成项目练习,然后您将结束使用现有协议或使用自定义协议。< / p>
因此,您的问题无法直接解决。您可以要求您的类C或D通过套接字发送序列化数据,而不是发送内存的结构副本,并将对象的类型作为第一个字节,下一个2/4字节的数据长度,实际数据到然后继续..然后实现一个读取第一个字节的读取器类,然后决定对象的类型,然后将调用委托给相应的类来读取其余的数据。
答案 3 :(得分:1)
首先,您的类层次结构看起来很可疑。根据您显示的内容,B
和C
之间没有任何关系,除了存在第三种类型A
,其中包含B
个对象和{ {1}}指针。然而,C
内的变量类型应该取决于B
对象内的指针指向C
的哪个子类?
这似乎是不必要的耦合。为什么不将A
中的B
字段合并到C
的各个子类中?
假设你已经修复了你的类层次结构,你就会遇到一个相对直接的问题,即想要在套接字上发送两种不同类型的消息(不同大小)中的一种。这是一个解决方案:
enum message_type {type1, type2};
class message_type1
{
...
};
class message_type2
{
...
};
// when sending message (pseudocode)
write message_type variable
write message_type1 object OR message_type2 object
// when reading message (pseudocode)
read message_type variable
if type1
read message_type1 object
else
read message_type2 object
当然,message_type1
和message_type2
可以通过作为相同基类的子类或相同模板等的实例来关联,以避免重复,如果这两种消息类型有一些共同点
编辑:您在评论中提到其他答案,您无法将邮件拆分为不同的数据包。你能澄清一下这意味着什么吗? “数据包”不是一个精确的术语:TCP具有段,UDP和IP具有数据报,以太网具有帧。这些都与您在套接字上调用send()
的次数有关(即两次调用send()
不必然意味着发送两个TCP段;相反,拨打send()
只需 确保您的数据会在一个网段中传输。
答案 4 :(得分:0)
Union可以用来解决问题。
struct B
{
int a;
bool d; //d = 0 for D and 1 for E
union
{
float b;
double c;
}
};