我有两个非常大的结构。两者都有很少的领域,但也有独特的领域。我正在尝试做的是根据要复制的结构的特定条件将这些公共字段的内容复制到第三个结构。现在主要问题来了。我不想编写两个不同的复制函数。比如
struct test1 {
//Has many members
} TEST1_INFO;
TEST1_INFO *g_TEST1_ptr;
struct test2 {
//Has many members
} TEST2_INFO;
TEST2_INFO *g_TEST2_ptr;
struct destination_struct {
//Has many members
} DEST_INFO;
DEST_INFO *g_DEST_ptr;
从结构 1 或结构 2 复制内容的一种方法是编写两个不同的复制函数并调用所需的一个,这就是我想要避免的。另一种方法是将条件放在单个函数中,并从所需的两个结构中复制内容,这是实现先前技术的另一种方法。
我想要的是这样的东西:
void * generic_pointer;
if(//mycondition)
generic_pointer = g_TEST1_ptr;
else
generic_pointer = g_TEST2_ptr;
g_DEST_ptr->member1 = generic_pointer->member1; ...
这可能吗???或者对于我想要实现的目标,是否有其他解决方案?请注意,这是特定于ANSI-C...
编辑 1:好的,在探索可能的替代解决方案时,我遇到了这个我以前从未使用过的工会,有人可以告诉我是否可以使用工会来解决我的问题?任何帮助都非常感谢。
不,不可能以你描述的方式。 取消引用 void 指针的唯一方法是先将其转换为另一种类型。
至于你如何做你想做的事,这取决于你所说的"共同领域"是什么意思。
如果您的含义是一组具有相同名称和相同类型的成员,则解决方案很简单。
struct CommonToBoth
{
/* list all the members in common to both your structs */
};
struct test1
{
struct CommonToBoth common;
/* other members specific to test1 here */
};
struct test2
{
struct CommonToBoth common;
/* other members specific to test2 here */
};
从那里,复制公共部分的方法很简单,如果你只需要一个浅拷贝(按值复制)。
struct test1 x;
struct test2 y;
/* initialise x */
y.common = x.common; /* this copies all the common parts by value */
这允许您根据需要将常见操作梳理到函数中。 如果您需要对任何公共部分进行深度复制(例如,一个成员是必须在复制时动态分配的指针),那么您需要编写一个函数来复制公共部分,而不仅仅是按值复制。
如果需要,您还可以将特定于每种struct
类型的零件放入其他struct
类型中。 这取决于您是否打算在其他struct
类型中重用这些部分。 所以你可以做到
struct test1 x;
struct test2 y;
/* initialise */
x.common = y.common;
x.specific = some_other_x.specific;
y.specific = some_other_y.specific;
x.specific = y.specific; /* this will have a type mismatch, so compiler error */
您可以像这样重新构建结构: 使用公共字段构建一个结构,并将其用于所需的 2 个结构。然后为不同的领域构建 2 个结构。这允许您编写更少的代码行进行传输。毕竟,您无法避免如何处理不同字段的问题。
struct common_tag { /* common fields */ };
struct flavor1_specifics_tag { /* fields, specific to flavor1 */ };
struct flavor2_specifics_tag { /* fields, specific to flavor2 */ };
struct flavor1_tag { struct common_tag common; struct flavor1_specifics_tag others; };
struct flavor2_tag { struct common_tag common; struct flavor2_specifics_tag others; };
有了这个,你可以以多态的方式使用 2 个结构。至少到位:
struct common_tag *flavor1_to_common( struct flavor1_tag * f1 );
struct common_tag *flavor2_to_common( struct flavor2_tag * f2 );
当你或其他人修改结构时,你也避免了将来令人讨厌的意外,而没有意识到你试图(滥用)使用共性。通过此处显示的策略,您想要做什么是相当明显的,未来的更改不太可能被您原本会采取的捷径所破坏。