C Союзы и полиморфизм [дубликаты]

Возможное дублирование:
Как я могу имитировать ОО-стиль полиморфизма в 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);
}

Это не так. Какие-либо предложения

 AFS23 мая 2012 г., 12:38
Я получаю сообщение об ошибке "несовместимый тип для аргумента 1"
 David Heffernan23 мая 2012 г., 12:54
Что ты собираешься делать после компиляции? Вы не можете сказать, является ли это A или B.
 user52975823 мая 2012 г., 12:36
Что значит "это не работает"
 AFS23 мая 2012 г., 13:19
Я сохраняю флаг int, который я могу проверить, чтобы увидеть, что это за тип

Ответы на вопрос(3)

Вы должны использовать явное преобразование типов:

A myA;
myMethod((C) myA);
 traducerad06 февр. 2019 г., 07:31
Как насчет __attribute __ ((transparent_union)), как указано выше?
 traducerad06 февр. 2019 г., 07:53
Пожалуйста, не стесняйтесь меня поправлять, но я чувствую, что многие люди придают большое значение переносимости компилятора. В большинстве случаев я чувствую, что быть совместимым с GCC более чем достаточно, нет необходимости быть совместимым со всеми экзотическими компиляторами. Linux afaik не компилируется со всеми компиляторами (может быть, только с gcc?)
 Some programmer dude06 февр. 2019 г., 07:57
@ traducerad Это сильно зависит от проекта. Является ли одна из целей проекта быть портативным? Тогда не используйте нестандартные непереносимые конструкции. Будет ли программа когда-либо использоваться только на одном компиляторе и только в узком диапазоне версий этого компилятора (расширения могут измениться, устареть или даже удалить в более новых версиях), а затем использовать любые расширения, которые вам нравятся. Лично я склонен идти на переносимый код, возможно, даже если не работаю над переносимым проектом.
 Some programmer dude06 февр. 2019 г., 07:50
@ traducerad Возможно, я не читал об этом. Но обратите внимание, что это расширение для конкретного компилятора, а не переносимое.
Решение Вопроса

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);

Видеть Атрибут типа transparent_union (только C).

 AFS23 мая 2012 г., 16:50
Спасибо. Дополнительный вопрос: хотя это работает, оно не работает при создании массива: C [5] myArray; С [0] = а; Это не работает и нуждается в явном приведении. Есть ли способ обойти это? Благодарность
 hroptatyr23 мая 2012 г., 17:00
на самом деле, это не так прозрачно, как вы думаете, правильное назначение будетC[0].a = a;

В C ++ вы можете перегрузитьmyFunction() и предоставить несколько реализаций.

В C вы можете иметь только одинmyFunction(). Даже если бы вы могли объявить функцию так, чтобы она могла приниматьA, B илиC (например, какvoid*), у него не было бы способа узнать, к какому из трех он был поставлен.

Ваш ответ на вопрос