如何在不同的头文件中具有相同类型和名称的两个结构而不会发生冲突?

时间:2019-06-08 11:20:37

标签: c data-structures struct header

我已经有一个结构小盒子,里面有两个原始变量(int标识符,int大小)。这个小盒子是用于构建即队列的高级结构的一部分。

现在,我在项目的一部分中遇到了一个问题,为此我想出了扩展此小盒子的解决方案,因此它具有另一条信息,例如int cost_to_send_it。虽然我不允许更改我的基础结构,但是有没有办法像Java中的方法重载那样以某种方式扩展此结构?拥有内部具有新属性而不是旧属性的新struct小框时,我是否仍可以使用我在较高结构上进行的所有操作?

2 个答案:

答案 0 :(得分:1)

这句话确定了答案:“ [是否]我仍然可以使用我在较高结构上进行的所有操作,同时在内部拥有带有颜色属性的新结构小框,而不是旧的小框?”答案是否定的。

如果所涉及的头文件和例程完全分开,则可以玩一些编译和链接“游戏”,即用一组结构定义一个源文件,用另一组结构定义另一个源文件。并确保它们永远不会根据结构定义进行交互。但是,由于您询问是否可以将使用一个定义定义的操作与替代定义一起使用,因此您必须强制一组代码使用这两个定义。 (另一种解决方案是将一个源文件设计为在不同情况下为其例程使用不同的名称,然后可以对其进行两次编译,一次是对结构的定义,一次是对另一种的定义,然后可以使用“相同的”在不同的结构上进行操作,但实际上它们是具有不同名称的不同例程,在某种意义上执行“相同”操作。)

虽然您可以在不同的翻译单元中对结构进行不同的定义,但是当结构或从其派生的任何类型(例如指向结构的指针)与不同翻译单元中的例程一起使用时,例程所期望的类型接收作为参数必须与作为参数传递给它的类型兼容,除了一些关于带符号类型,添加限定符等的规则,在这里没有帮助。

要使两个结构兼容,它们的成员之间必须一对一对应,它们本身必须具有兼容类型(C 2018 6.2.7 1)。具有不同成员数的两个结构没有一对一的对应关系。

答案 1 :(得分:0)

  

有没有办法像某种方法那样扩展这种结构   Java左右重载?

在方法重载中,编译器通过检查对该名称的方法的每次调用的参数来在同名方法中进行选择。注意,这是一个完全本地化的决定:不考虑优化问题,编译器的选择只影响单个语句的代码生成。

  

在哪里我仍然可以使用所有操作   在拥有新的struct smallbox的同时,我在较高的struct上拥有   内部具有color属性,而不是旧属性?

我认为您要查找的是多态性,而不是过载。请注意,在Java(以及C ++和其他我所知道的其他语言都支持此功能)中,它基于不同命名类型之间的类型/子类型关系。我不知道有什么语言可以让您重新定义类型名称,并使用两种不同的类型,就好像它们在任何意义上都是相同的。当然C不会。

但是,有一些替代方法。最简洁的做法是创建一个新的名称不同的结构类型,其中包含旧的实例:

struct sb {
    int id;
    int size;
};

struct sb_metered {
    struct sb box;
    int cost;
}

通过指针而不是通过值处理这些对象的单个实例的函数很容易满足:

int get_size(struct sb *box) {
    return sb->size;
}

int get_cost(struct sb_metered *metered_box) {
    return metered_box->cost;
}

int main() {
    struct sb_metered b = { { 1, 17}, 42 };

    printf("id: %d, size: %d, cost: %d\n",
        b.id,
        get_size(&b.box),
        get_cost(&b));
}

请注意,该 不允许您形成实际上包含子类型实例的超类型(struct sb)的数组,也不允许按值传递或返回该子类型的结构对象就像它们是超类型的对象一样。