【问题标题】:C Unions and Polymorphism [duplicate]C联合和多态[重复]
【发布时间】:2012-05-29 21:29:33
【问题描述】:

可能重复:
How can I simulate OO-style polymorphism in C?

我正在尝试使用联合在 C 中创建多态性。我执行以下操作。

typedef struct{
...
...
} A;

typedef struct{
...
... 
} B;

typedef union{
        A a;
        B b;
}C;

我的问题是:我怎样才能有一个采用 C 类型但也允许 A 和 B 的方法。我希望以下工作:

如果我定义一个函数:

myMethod(C){
...
}

那么,我想让它工作:

main(){
A myA;
myMethod(myA);
}

它没有。有什么建议吗?

【问题讨论】:

  • “不行”是什么意思
  • 我收到“参数 1 的类型不兼容”的错误
  • 编译后你打算做什么?你无法分辨它是 A 还是 B。
  • 我保留了一个 int 标志,我可以测试它以查看实际类型是什么

标签: c struct polymorphism unions


【解决方案1】:

GNU 和 IBM 支持 transparent_union 扩展:

typedef union __attribute__((transparent_union)) {
        A a;
        B b;
} C;

然后您可以透明地使用As 或Bs 或Cs:

A foo1;
B foo2;
C foo3;
myMethod(foo1);
myMethod(foo2);
myMethod(foo3);

The transparent_union type attribute (C only)

【讨论】:

  • 非常感谢。后续问题:虽然这有效,但当我创建数组时它不起作用: C[5] myArray; C[0]=一个;这不起作用,需要显式转换。有什么办法吗?谢谢!
  • 确实,没有你想的那么透明,正确的赋值应该是C[0].a = a;
【解决方案2】:

简短的回答是,在 C 中,你不能。

在 C++ 中,您可以重载 myFunction() 并提供多个实现。

在 C 中,您只能有一个 myFunction()。即使您可以声明该函数以使其可以采用ABC(例如void*),它也无法知道它提供了三个中的哪一个。

【讨论】:

    【解决方案3】:

    你必须使用显式类型转换:

    A myA;
    myMethod((C) myA);
    

    【讨论】:

    • 上面指定的 __attribute__((transparent_union)) 怎么样?
    • @traducerad 也许,我还没有读到它。但请注意,它是特定于编译器的扩展,不可移植。
    • 请随时纠正我,但我觉得很多人都非常重视编译器的可移植性。在大多数人的情况下,我觉得符合 GCC 就绰绰有余了,不需要符合所有异国情调的编译器。 Linux 是 afaik 不能用所有编译器编译(也许只有 gcc?)
    • @traducerad 这与项目高度相关。该项目的目标之一是便携吗?然后不要使用非标准的不可移植结构。该程序是否只能在单个编译器上使用,并且只能在该编译器的狭窄版本范围内使用(扩展可能会更改,被弃用甚至在新版本中被删除)然后继续使用您喜欢的任何扩展。我个人倾向于使用可移植代码,即使不从事可移植项目。
    猜你喜欢
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多