Я сделал простой эксперимент, файл «.h» с определением класса и определение Funciton, как показано ниже:Файл заголовка содержит тело функции, приведет к дублированию определения?
$cat testInline.h
#pragma once
class C{
public:
void f(){}
};
void g(){}
Тогда 2 пользователей этого .h файла:
$cat use01.cpp
#include"testInline.h"
void g01(){
g();
C obj1;
obj1.f();
}
$cat use02.cpp
#include"testInline.h"
int main(){
g();
C obj2;
obj2.f();
return 0;
}
компилировать их вместе и получает ошибку:
$g++ use01.cpp use02.cpp
duplicate symbol __Z1gv in:
/var/folders/zv/b953j0_55vldj97t0wz4qmkh0000gn/T/use01-34f300.o
/var/folders/zv/b953j0_55vldj97t0wz4qmkh0000gn/T/use02-838e05.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Выглядит очень странно: Я использовал «#pragma один раз», до сих пор я не могу остановить компилятор сообщать дублированный определение г() (__ Z1gv как имя коверкая)
Тогда я изменил testInline.h-> г (определение), чтобы быть похожим:
inline void g(){}
Ну, он компилирует. Разве это не на C++, что ключевое слово «inline» в принципе бесполезно, потому что компиляторы решат, будет ли он встроить функцию или нет?
И, почему C :: f() с кодом в файле .h не сообщает о дублировании, а функция C-стиля g()? И почему класс C не «должен» добавить «inline» для своей функции «f()», а g() должен использовать «inline»?
Надеюсь, я четко изложил свой вопрос. Спасибо за вашу помощь.
«C++ требует, чтобы функция скомпилировалась», как будто «она была встроена», рассмотрим рекурсивную функцию. ;-) –