より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

ヘッダーファイルとソースファイルは同じ名前でなくて良かった

ヘッダーファイルとソースファイルの名前は同じにするものだと思っていました。

ヘッダーファイルがa.hであれば、ソースファイル(*.cpp)がa.cppという形です。

C++の本を読んでいたのですが、そうでなくてもコンパイルは通るようです。

a.cppに以下のようなソースを記載します。

#include <iostream>

using namespace std;

void a() {
    cout << "a";
}

これをa.hではなく、b.hというヘッダーファイルで定義します。

void a();

f:id:rimever:20190813211910p:plain

これをmain関数から呼び出してみます。

#include <iostream>
#include "b.h"

int main() {
    a();
    return 0;
}

f:id:rimever:20190813212305p:plain

いけますね。

となると、いたずらをしたくなります。

重複する関数が存在すると?

さらに、b.cppというファイルを定義づけて、全く同じ引数のa関数を定義してみます。

f:id:rimever:20190813212649p:plain

すると、コンパイルエラーとなります。

duplicate symbol __Z1av in:

CMakeFiles/list4_18.dir/a.cpp.o

CMakeFiles/list4_18.dir/b.cpp.o

ld: 1 duplicate symbol for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

make[3]: *** [list4_18] Error 1

make[2]: *** [CMakeFiles/list4_18.dir/all] Error 2

make[1]: *** [CMakeFiles/list4_18.dir/rule] Error 2

make: *** [list4_18] Error 2

ヘッダーファイルは複数のソースファイルの関数を定義できるか?

  • a.cpp ... void a()を実装
  • b.cpp ... void b()を実装
  • ab.h ... void a(); void b(); と宣言

main関数でa();とb();を呼び出します。

f:id:rimever:20190813213141p:plain

通るんですね。これが。

ソースファイルとヘッダーファイルは1対1ではなくても良いようです。

まとめ

とはいえ、ヘッダーファイルとソースファイルの名前は同じで1対1にした方がいいでしょう。

ではないと、混乱します。