2012/06/20

C++ ファイルの分割

C++で書くとソースが長くなって読みにくくなる。そこでファイルを分割するのだが、なるべく標準的な分割方法にしたい。とりあえずヘッダファイルにクラスを宣言(インライン関数可)して、定義をcppファイルに書く。mainは切り離した方が何かとよいと思われるので、別ファイルにしてみた。

オープンソースのソースファイルを見るときなどは、こういう知識がないと、さっぱり分からないということになってしまう。特にヘッダファイルの使い分けが不明だったり。C++の学習は全体像から細部へと向かうつもり。

a.h

#ifndef A_H
#define A_H
//クラスの宣言
class Aclass{
public:
  Aclass();
  ~Aclass();
  void method();
};

#endif
ヘッダファイルはクラスの宣言を書いておいて、中身の実装部はcppに書くようだ。実際オープンソースのソースファイルを見ると、そういう使い分けになっていた。それなりの規模のクラスだと、ヘッダファイルとクラスファイルが1対1の関係になっているようだが、ヘッダファイルが多すぎると管理しにくくなるので、ある程度関連あるクラスはひとつのヘッダファイルにまとめた方がよさそうだ。
またマクロ #ifndef、#define、#endif を使ってクラスの重複定義を防止している。重複してしまうとコンパイルエラーとなってしまう。多くのファイルを使い始めると必要性が見えてくるようだ。マクロは#ifndef の次の行の #define A_H が「もし定義されていなければコンパイルする」という意味。もし定義されていれば#endifまで無視する。#が付いているので、プリプロセッサの処理となる。

a.cpp

#include "a.h"
#include <iostream>
//コンストラクタ
Aclass::Aclass(){
  std::cout << "constructor\n";
}
//デストラクタ
Aclass::~Aclass(){
  std::cout << "destructor\n";
}
//メンバ関数
void Aclass::method(){
  std::cout << "Aclass::method()\n";
}
拡張子.cppのファイルが実装部分で、関数の中身を書いている。

main.cpp

#include "a.h"

//メイン関数
int main(void){
  Aclass *oAclass;
  oAclass = new Aclass();
  oAclass->method();
  delete oAclass;
  return 0;
}
メイン関数は指示を出すスタート地点なので、あえて別にしておきたい。再利用を前提としたクラスに対して、メイン関数は毎回書き直すと思われるので。

上記3ファイルを一気にexeにする場合は、以下のように打ってコンパイルする。

g++ a.h a.cpp main.cpp
下は出来た a.exe の実行画面
constructor
Aclass::method()
destructor


C++言語 Meadow & MinGW GCC 目次