具有N个字段的A型有可能将其合并到具有N + x个字段的B型新对象中?

问题描述:

假设我们有具有N个字段的A型有可能将其合并到具有N + x个字段的B型新对象中?

struct Message { 
    char * topic; 
    int topicLength; 

    void * data; 
    int dataLength; 
}; 

一个实例,我们希望重新为其他类型

struct CoreMessage { 
    int messaageId; 

    char * topic; 
    int topicLength; 

    void * data; 
    int dataLength; 

    char * senderId; 
    int senderIdLength; 
}; 

的对象,我们safly转Message ACoreMessage B可以吗? C中没有复制内容的东西,类型部分重叠,如下所示?

+0

显示的代码是如何有“的'结构Message'实例”样本将帮助。根据该代码,存在各种解决方案。 – chux

+0

要做你在问什么,在对象的两边必须有未使用的存储 - 所以你不能在原始类型的数组上做这个,只是一次性的。如果你发现实际上值得这样做的情况,汇编语言是正确的答案。这将是极其特殊的目的。 – jthill

不,你不能做你要求的。你可以接近,但是,如果你愿意改变的struct CoreMessage布局像这样:

struct CoreMessage { 
    struct Message message; 

    int messaageId; 

    char * senderId; 
    int senderIdLength; 
}; 

注意struct CoreMessage则包含实际struct Message为成员(而不是一个指向一个)。然后,给...

struct CoreMessage cm; 
struct CoreMessage *cmp = &cm; 
struct Message *mp = &cm.message; 

...你有(void *) cmp == (void *) mp,这可能是一些你可能想要做这样的东西是有用的。这也会自动调整以更改为struct Message

或者,你可以做这样的事情:

struct Message { 
    char * topic; 
    int topicLength; 

    void * data; 
    int dataLength; 

    maximum_alignment_requirement_t resv1; 
    char resv2[AS_MANY_BYTES_AS_ANY_MESSAGE_TYPE_MAY_NEED_INCLUDING_PADDING]; 
}; 

struct CoreMessage { 
    char * topic; 
    int topicLength; 

    void * data; 
    int dataLength; 

    maximum_alignment_requirement_t resv1; 

    int messaageId; 

    char * senderId; 
    int senderIdLength; 
}; 

struct Message msg; 
struct CoreMessage *cmp = (struct CoreMessage *) &msg; 

这有工作,你会希望(和一些系统接口的工作几乎这样)的概率很高,但C没有保证那那些相应的元素将在两种不同的struct类型中以相同的方式布置。

也请注意,在struct Message的成员对应的成员后移动CoreMessage.messageId并非偶然。如果你不这样做,安排相应的布局就困难得多,而第一个选择的指针值等价取决于它。

不确定你的意思是“安全转向”,但我希望答案是“不”。结构是不同的,当然小的不可能神奇地被期望扩展到以前没有使用的内存中。

有一个在C.

当然,你可以声明 CoreMessageMessage方面,但它不会帮助相反从更小的变换较大型除外“重叠类型”的没有概念

使共享信息更容易转移:

struct CoreMessage { 
    int messageId; 
    struct Message message; 
    char *senderId; 
    int senderIdLength; 
}; 

现在,如果我们有:

struct Message a = { ... }; /* fully initialized */ 
struct CoreMessage b; /* we want to convert Message into this */ 

,我们可以这样做:

b.messageId = 4711; 
b.message = a; /* Copy all Message data over. */ 
b.senderId = "foo"; 
b.senderIdLength = 3; 

虽然没有什么是自动的,但你必须自己动手。

+0

复制的事实是我希望逃脱..( – DuckQueen

我不确定您的意思是“转入”。我不知道你如何能够为你做到这一点。

但是,C标准允许编译器在结构体的字段之间放置未使用的空间,所以一般情况下都不会有效。你可以让“CoreMessage”包含一个“消息”,并用一个赋值生成结果。

你可以用匿名结构/联合来伪造这个。无可否认,自从C11以来,匿名结构已经被标准化,但许多流行的编译器都支持它们作为年龄的延伸。

也就是沿着这些东西,无可否认,低于漂亮,线条:

struct Message { 
    char * topic; 
    int topicLength; 
    void * data; 
    int dataLength; 
    char * senderId; 
    int senderIdLength; 
}; 

struct CoreMessage { 
    int messageId; 
    union { 
     struct Message; 
     struct Message message; 
    }; 
};