2013-09-01 6 views
0

я застрял с классической Multiple проблемы наследования в С.Множественное наследование в C

я создал исходные файлы Stack.c и Queue.c. Оба они # включают файл Node.c (который содержит функции для выделения и освобождения памяти). Теперь я пытаюсь реализовать другую программу в одном файле, для которой мне нужно включить как Stack.c, так и Queue.c. Я попытался # включить оба файла, но компилятор бросает ошибку конфликтующего типа.

Каков наилучший способ сделать это?

Спасибо заранее!

+1

Наследование? В C? У вас есть занятия в C ??? –

+3

Я бы начал с использования C++. Наследование в C - абсолютная девка. В стороне, такие вещи, как «Оба из них # включают файл Node.c», вызывают серьезные проблемы. Не включайте файлы .c друг в друга. Включите * declarations * (Node.h) в файл заголовка и сохраните единственную реализацию 'Node.c' * * в своем * собственном * исходном файле; НЕ включено в несколько исходных файлов. – WhozCraig

+0

@ AndreyChernukha Я использовал слово Inheritance не в контексте самой C. Но да, должен был использовать ** Linking ** вместо этого. – maygnify

ответ

7

Вызов этого «множественного наследования» может ввести в заблуждение, поскольку множественное наследование является объектно-ориентированное программирование вопрос, который возникает не в С.

Мне кажется, что ваша трудность может быть, что вы пытаетесь # включают исполняемый код (то есть .c файлов) вместо ссылки на файлы .c и #include header (.h) файлы, которые предоставляют декларации для функций в файлах .c.

+0

+1 У меня очень высокая уверенность, это как раз проблема (как будто это не было очевидно). – WhozCraig

+0

Спасибо @Simon. Это именно то, что я пытался сделать. – maygnify

1

Это произойдет, если вы получили исходные файлы (.c) ... вы должны (по большей части) #include заголовки (.h). Заголовки обычно предоставляют прототипы функций, typedefs, макросы и т. Д., Но не учитывают фактическую реализацию.

Фактическое выполнение функций, определений переменных и т. Д. Должно происходить ровно один раз для каждой единицы компиляции и обычно в файле .c.

Если у вас есть другой код, который нужно повторно использовать функции или переменные, определенные в другом модуле компиляции (например Stack.c), вы бы #include Stack.h, которая обеспечивала бы прототипы функций, глобальные имена переменных и т.д., которые вам может понадобиться.

После того как вы скомпилируете все свои единицы компиляции, это задача компоновщика, чтобы выяснить, какой объектный файл или библиотека определяется функцией или переменной. Вы сильно усложняете ее работу, когда вы #include "X.c" в другом компиляторе, потому что тогда вы (символов, так как компоновщик любит их называть).

Вкратце, используйте заголовки и позвольте компоновщику выполнять свою работу.


Относительно примечания это не имеет ничего общего с множественным наследованием. Это объектно-ориентированная проблема для таких языков, как C++. Собственное имя для того, что вы описываете, это «столкновение символов» или «дублирующие символы».

+0

Спасибо! Это кажется правильным. – maygnify

0

Не видя подробностей вашей программы, трудно сказать. Однако ошибки конфликтующих типов часто могут быть исправлены просто путем переупорядочения кода или добавления прототипов функций.

Вы видите, что функции должны быть описаны до их вызова при чтении исходного файла сверху вниз. например:

char foo1() 
{ 
    char blah = foo2(); 
    return blah; 
} 
char foo2() 
{ 
    return 'a'; 
} 

Вы хотите получить противоречивую ошибку типа, потому что, когда он находится внутри foo1, он не видел заявления на foo2 еще. Таким образом, он предполагает, что независимо от того, что будет foo2, он вернет int. Но на самом деле он возвращает char. Эти два не совпадают, поэтому ... сообщается о конфликтующем типе.

Вы можете это исправить, имея foo2 прийти первым в исходном коде, или путем вставки прототипа функции:

char foo2(); // function prototype 
char foo1() 
{ 
    char blah = foo2(); 
    return blah; 
} 
char foo2() 
{ 
    return 'a'; 
} 

Вы также можете получить противоречивую тип ошибки, если вы включите исходные файлы, по той же причине , #include "Node.c" - это, по сути, копия. Было бы неплохо перейти от Node.c к включению Node.h с внешними функциями. Вы также можете избежать множества проблем, если вы дадите префиксы своим именам функций в исходных файлах, которые вы планируете включить, например .... nodeInsert, nodeDelete, nodeCompare и т. Д.

Смежные вопросы