Сегодня я написал короткий пример, чтобы посмотреть, скомпилируется ли он, и я был очень удивлен, когда обнаружил, что это сработало!
Вот пример:
hello.h
#ifndef HELLO_H
#define HELLO_H
// Function prototype
void say_hello();
#endif
hello.cpp
ПРИМЕЧАНИЕ: Это НЕ включает "hello.h", как это было бы в каждом примере C ++, который я когда-либо видел в истории навсегда!
// #include "hello.h" <-- Commented out. The corresponding header is NOT included.
#include <iostream>
void say_hello() {
std::cout << "Hello!" << std::endl;
}
main.cpp
#include "hello.h"
int main() {
say_hello();
}
Затем я скомпилировал "hello.cpp" в статическую библиотеку следующим образом:
g++ -c hello.cpp
ar -rvs libhello.a hello.o
Затем я скомпилировал «основное» приложение и связал его с библиотекой
g++ -o main main.cpp -L. -lhello
И запустил его, и он прекрасно выполнил!
./main
Здравствуйте!
Хотя я был удивлен ... Я понимаю, почему это работает. Это потому, что функция в "hello.cpp" не объявлена как статическая, поэтому имеет внешнюю связь и может быть видна снаружи. Установка статического состояния приведет к сбою ссылки из-за неопределенной ссылки.
Так вот в чем вопрос ... Если это работает, то почему все ВСЕГДА включают заголовочный файл ".h" с объявлениями функций в файле реализации ".cpp". Ясно, что если это просто определение свободных функций, это не обязательно, и все будет работать нормально, если заголовочный файл не включен.
Так почему мы всегда включаем это? - Это просто общее непонимание того, как работает компоновщик? Или есть что-то еще?