レベル: 中級 Michael Galpin (mike.sr@gmail.com), Developer, Vitria Technology
2007年 7月 10日 大抵の人は「Eclipse」を考えるときに「Java™ IDE」を連想しますが、Eclipse はそれだけにとどまりません。適切なプラグインを使えば、Eclipse で PHP、Ruby、Groovy、C、そして C++ を扱うことができます。この記事では、Eclipse CDT (C/C++ Development Toolkit) の使い方から始め、CDT と C++ STL (Standard Template Library) を使用して、プロセスを合理化し、C++ ならではの強力な機能を利用する単純なアプリケーションをビルドします。
この記事は「Eclipse Platform を使用した C/C++ 開発」のフォローアップで、Eclipse CDT を使用した C++ 開発を学びたいと思っている C++ 開発者を対象としています。今回開発するのは単純な C++ アプリケーションです。このアプリケーションでは C++ STL を利用するため、読者は STL の十分な知識があること、そして継承やポリモーフィズムなどのオブジェクト指向プログラミングの基本原理を理解していることを前提とします。Eclipse についての知識があると役に立ちますが、必須ではありません。
始める前に
以下をインストールする必要があります。
-
Eclipse
- CDT を使用します。これは Eclipse のプラグインなので、当然 Eclipse が必要です。この記事では Eclipse V3.2 を使用します。
-
Java Runtime Environment
- ビルドするのは C++ アプリケーションですが、使用するのは Eclipse です。Eclipse は Java アプリケーションそのものなので、JRE
(Java Runtime Environment) が必要となります。この記事で使用する Eclipse V3.2 には、V1.4 以降の
JRE が必要です。Java 開発にも Eclipse を使用するのであれば、JDK (Java Development Kit) を入手してください。
-
Eclipse CDT (C/C++ Development Toolkit)
- この記事で話題とする CDT はもちろん必須です。初期バージョンのEclipse に CDT をインストールする手順については、2003年の
developerWorks の記事「Eclipse Platform を使用した C/C++ 開発」を読んでください。
-
Cygwin
- Microsoft Windows® をご使用の場合は、Linux® のような環境を Windows で実現する Cygwin
が役立つはずです。
-
GNU CDT (C/C++ Development Tools)
- CDT ではコードのコンパイル、プロジェクトのビルド、アプリケーションのデバッグに標準GNU C/C++ ツールを使用します。具体的には、C++
(g++)、make、および GDB (GNU Project Debugger) に対応した GCC (GNU Compiler Collection)
です。Linux または Mac OS X を使用しているプログラマーであれば、おそらくこれらのツールはマシンにインストールされていると思うので、この記事では
Windows でのツールのセットアップ手順を記載します。
Eclipse CDT
Eclipse CDT は、Eclipse を強力な C/C++ IDE に変換する Eclipse プラグインです。このプラグインは、プロジェクト管理、統合デバッグ、クラス・ウィザード、自動ビルド、構文色分け、そしてコード補完など、Java
開発者が享受している Eclipse の優れた機能の多くを C/C++ 開発者に提供することを目的に設計されました。Java IDE として
Eclipse を使用する場合には JDK を統合して活用しますが、 それと同じく、CDT は標準 C/C++ ツール (g++、make、GDB
など) を統合して活用します。そのため、これらのツールがすぐに利用できて大抵の C++ 開発に用いられている Linux で、CDT の人気が高まりました。Windows
でも CDT をセットアップして同じツールを使用することはできます。Windows C++ 開発者の興味をさらに引き付けるため、CDT を Microsoft
の C++ ツールと連動させる取り組みも現在行われているところです。
CDT のインストール手順
Eclipse がインストール済みで、実行可能な状態であることを前提とします。この状態になっていない場合は、Eclipse の Web サイトで
Eclipse を立ち上げて実行する方法を調べてください。それでは早速、CDT のインストールに取り掛かります。CDT は Eclipse のプラグインなので、Eclipse
の Software Updates 機能を使用します。Help > Software Updates > Find and Install を選択してください。
図 1. Eclipse の Software Updates
次にSearch for new features to install を選択します。
図 2. 新規機能の検索
新しいバージョンの Eclipse をお使いの場合は、Callisto または Europa ディスカバリー・サイトが組み込まれているはずです
(編集者の注記: この記事が作成された 2007年4月の時点では、Europa リリースはまだ計画段階でした。ただし、Europa のインストール手順は
Callisto の場合と同様であると見込まれます)。ディスカバリー・サイトを選択して Finish をクリックします。
図 3. Callisto Discovery Site
Eclipse が Callisto Discovery Site のミラー・サイト・リストからサイトを選択するように求めるので、もっとも適切だと思えるサイトを選択してください。すると、Callisto
Discovery Site にあるプラグインのリストが表示されます。ここでは C and C++ Development を選択して Next をクリックします。
図 4. 入手可能な Callisto プラグイン
CDT の使用条件に同意するよう求められます。同意してから Next をクリックします。ダウンロードおよびインストール内容のサマリーが表示されたら、Finish をクリックします。
図 5. ダウンロードおよびインストールのサマリー
Eclipse の Update Manager が、前に選択したミラー・サイトから CDT プラグインをダウンロードします。CDT の合計サイズは約
11 MB なので、インターネットの接続スピードによってはダウンロードに数分かかる場合があります。すべてのダウンロードが完了すると、新規機能のインストール確認画面が表示されます。Install All をクリックしてください。
図 6. インストールの確認
CDT のインストールが完了すると Eclipse を再起動するよう求められるので、すぐに再起動してください。Eclipse が再起動したら、CDT
の準備は完了です。
Windows での構成
Eclipse を Linux または Mac OS X で実行しているのであれば、CDT を使って C++ アプリケーションの開発をすぐに始められますが、Windows
で実行している場合にはさらにいくつかのステップが必要です。前述したように、CDT は標準 GNU C++ 開発ツール、g++、make、および
GDB に依存します。Linux や Mac OS X には通常、これらのツールは組み込まれていますが、Windows ではその限りではありません。でも心配無用です。これらのツールは
Windows に簡単にインストールすることができます。そのもっとも手軽な方法は、Cygwin をインストールすることでしょう。Cygwin
は Linux のような環境を Windows で実現します (「参考文献」を参照)。Cygwin をインストールするときには、インストールするパッケージを選択しなければなりません。その際には必ず、開発セクションに進んで
gcc (g++、make、および GDB) を選択してください。こうすると、それぞれの前提条件も同時にインストールされます。
Cygwin のインストールが完了したら、g++、make、GDB をパスに追加します。それには、g++、make、GDB があるCygwinの
bin ディレクトリーをパスに追加すると簡単です。追加し終えたら、Eclipse を再起動してください。
宝くじのアプリケーション
ここまでのところで、CDT を使用してアプリケーションを開発するための準備はすべて完了しました。手順を開始する前に、開発するアプリケーションについて説明しておきます。サンプル・アプリケーションは、抽選番号を生成するための単純なコマンド・ライン・プログラムです。多くの州には宝くじがありますが、そのルールは州によってかなり異なります。このアプリケーションでは、ユーザーが特定の州の宝くじを選んで抽選番号を生成できるようにします。これは、C++
のポリモーフィック動作のサポートを利用する賢い方法です。
プロジェクトの作成手順
Eclipse では各種のプラグインがそれぞれのコマンドとビューをカスタマイズできるように、パースペクティブの概念を採用しています。Eclipse
を起動すると、デフォルトでは、Java パースペクティブが表示されます。CDT には固有のパースペクティブが組み込まれているため、そのパースペクティブに切り替えなくてはなりません。Window > Open Perspective > Other を選択すると使用可能なパースペクティブのリストが表示されるので、C/C++ パースペクティブを選択して OK をクリックします。
図 7. C/C++ パースペクティブの選択
Eclipse の画面は図 8 のようになっているはずです。
図 8. C/C++ パースペクティブ
Eclipse はコードをプロジェクトに編成するため、ここで、新規プロジェクトを作成します。それには、File > New > Managed Make C++ Project を選択します。
図 9. 新規 C++ プロジェクト
お気付きかもしれませんが、プロジェクトには複数のオプションがあります。今回目的としているのは C++ プロジェクトで、選択したのは「Managed
Make」です。これを選択すると、Eclipse が make ファイルを作成してくれるからです。一方、「Standard Make」のオプションを選択して、独自の
make ファイルを作成することもできます。現在、New Project ウィザードが表示されているはずなので、プロジェクトに Lottery という名前を付けて Finish をクリックしてください。
空のプロジェクトが作成され、C/C++ Projects ウィンドウに表示されます。このプロジェクトを右クリックして New > Source Folder を選択すると、「New Source Folder」ウィザードが表示されます。ここで、フォルダーに src という名前を付けて Finish をクリックします。
基本 Lottery クラス
コードを作成する準備が整いました。まず始めに作成するのは、アプリケーションの実行可能ファイルです。先ほど作成したソース・フォルダーを右クリックして
New > Source File を選択します (図 10 を参照)。
とりあえず、空の main メソッドを作成します。これは単なるプレースホルダーで、プロジェクトの残りの部分を作成してからこのメソッドに追加していきます。
プロジェクトを保存すると、後は Ecipse が自動的に処理してくれます。コンパイルが正常に完了すると、コンソールにそれを示す出力が表示されるはずです。
最初のクラスを作成する準備ができたので、作成したソース・フォルダーを右クリックして New > Class を選択します。
図 10. クラスの新規作成
表示された New Class ウィザードで、クラスの名前空間に lotto を指定し、クラス名として Lottery と入力します。
図 11. Lottery クラス
これで、このクラスのスタブが Eclipse によって作成されます。CDT には嬉しい機能がたくさんあります。まず、ヘッダー・ファイルに適切なコンパイラー・ディレクティブを生成してくれます。また、個別のインターフェース・ファイル
(Lottery.h) と実装ファイル (Lottery.cpp) を生成して、ベスト・プラクティスを奨励します。さらに別のベスト・プラクティスとして、クラスのデストラクターを仮想に設定します。これらのクラスのソース・コードは、それぞれリスト
1 とリスト 2 のように入力できます。
リスト 1. Lottery.h
#ifndef LOTTERY_H_
#define LOTTERY_H_
#include <string>
#include <sstream>
#include <cstdlib>
#include <time.h>
using namespace std;
namespace lotto
{
class Lottery
{
protected:
int ticketSize, maxNum;
int* generateNumbers();
public:
Lottery(int,int);
virtual ~Lottery();
virtual string printTicket();
};
}
#endif /*LOTTERY_H_*/ |
リスト 2 は、Lottery クラスの実装ファイルです。
リスト 2. Lottery.cpp
#include "Lottery.h"
namespace lotto
{
Lottery::Lottery(int size, int num)
{
this->ticketSize = size;
this->maxNum = num;
}
Lottery::~Lottery()
{
}
int* Lottery::generateNumbers()
{
int* allNums = new int[this->maxNum +1];
for (int i=0; i <= this->maxNum ; i++)
{
allNums[i] = 0;
}
int* nums = new int[this->ticketSize];
for (int i=0; i < this->ticketSize; i++)
{
int val = 1 + rand() % (this->maxNum);
if (allNums[val])
{
i--;
}
else
{
nums[i] = val;
allNums[val] =1;
}
}
return nums;
}
string Lottery::printTicket()
{
ostringstream str;
int* nums = this->generateNumbers();
for (int i=0;i< this->ticketSize; i++)
{
str << *nums << ' ';
nums++;
}
return str.str();
}
} |
このコードの内容を説明しましょう。まず、Lottery クラスには 2 つの属性があります。ticketSize 属性は抽選券の番号の数で、もう一方の maxNum 属性は抽選番号の最大値です。後で、例として挙げるフロリダ州の宝くじでは、1 から 53 のなかから 6 つの番号を選ぶので、つまり、ticketSize は 6 となり、maxNum は 53 となります。
generateNumbers メソッドは、抽選券の番号に対応する数値の配列を生成します。このメソッドは STL 関数 rand() を使用して無作為に数値を生成します。この allNums 配列を使用して今までに生成された数値が追跡されるため、抽選券の番号が重複することはありません。最後に printTicket() が抽選券のストリング表現を作成します。
この 2 つのファイルを保存すると、Eclipse がプロジェクトを自動的にビルドします。この場合も、プロジェクトを保存すると、プロジェクトがコンパイルされてコンソールにコンパイル・メッセージが表示されます
(リスト 3 を参照)。
リスト 3. コンパイラーによるコンソールでの出力
**** Build of configuration Debug for project Lottery ****
make -k all
Building file: ../src/Main.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Main.d" -MT"src/Main.d"
-o"src/Main.o" "../src/Main.cpp"
Finished building: ../src/Main.cpp
Building target: Lottery
Invoking: MacOS X C++ Linker
g++ -o "Lottery" ./src/Lottery.o ./src/Main.o
Finished building target: Lottery
Build complete for project Lottery |
MegaLottery クラス
ヘッダー・ファイルを見るとわかるように、printTicket() メソッドは仮想メソッドとして宣言されているため、Lottery をサブクラス化してこのメソッドをオーバーライドすることができます。このようにしている理由は、一部の州では「メガ (mega)」番号を使った宝くじがあるためです。これは抽選番号とは別に引く番号で、抽選券はこの番号にも一致しなければなりません。次に作成するのは、これらの州を対象とした
MegaLottery クラスです。このクラスが、Lottery をサブクラス化します。
もう一度、前と同じようにソース・フォルダーを右クリックして New > Class を選択します。New Class ウィザードで今回宣言する新規クラスには同じ名前空間を指定しますが、名前には MegaLottery と入力します。
図 12. MegaLottery クラス
Lottery をサブクラス化するには、Base Classes セクションの隣にある Add ボタンを選択します。この操作によって、Choose Base Class ダイアログが表示されます。クラスの名前を入力し始めると、Eclipse
がすぐに基底クラスの候補リストを絞り込みます。Lottery を選択して OK をクリックしてください。
図 13. 基底クラスの選択
MegaLottery のコードは、リスト 4 とリスト 5 のように入力します。
リスト 4. MegaLottery.h
#ifndef MEGALOTTERY_H_
#define MEGALOTTERY_H_
#include "Lottery.h"
using std::string;
namespace lotto
{
class MegaLottery : public lotto::Lottery
{
protected:
int maxMegaNum;
public:
MegaLottery(int,int,int);
virtual ~MegaLottery();
string printTicket();
};
}
#endif /*MEGALOTTERY_H_*/ |
リスト 5 は、MegaLottery クラスの実装ファイルです。
リスト 5. MegaLottery.cpp
#include "MegaLottery.h"
using namespace std;
namespace lotto
{
MegaLottery::MegaLottery(int ticketSize, int maxNum, int maxMegaNum) :
Lottery(ticketSize,maxNum)
{
this->maxMegaNum = maxMegaNum;
}
MegaLottery::~MegaLottery()
{
}
string MegaLottery::printTicket()
{
ostringstream tick;
tick << Lottery::printTicket() << " Mega: ";
int mega = 1 + rand() % this->maxMegaNum;
tick << mega;
return tick.str();
}
} |
Lottery と MegaLottery との大きな違いは、MegaLottery には maxMegaNum という追加の属性がある点です。この属性はメガ番号の取り得る最大値で、printTicket() メソッドをオーバーライドします。MegaLottery クラスでは、初めに基底クラスによって抽選券の最初の部分が生成され、次にメガ番号が生成されて抽選券のストリング表現に追加されます。
ここで必要なのはさまざまな宝くじを作成する方法です。そこで Factory Pattern クラスを使用して、まず LotteryFactory クラスを追加します。すべての Lotteries は同じファクトリーからのものでなくてはならないので、LotteryFactory は singleton にします。このクラスのコードは、リスト 6 およびリスト 7 のとおりです。
リスト 6. #ifndef LOTTERYFACTORY_H_
#define LOTTERYFACTORY_H_
#include "Lottery.h"
namespace lotto
{
class LotteryFactory
{
public:
enum State { California, Florida };
static LotteryFactory* getInstance();
Lottery* getLottery(State);
private:
LotteryFactory();
};
}
#endif /*LOTTERYFACTORY_H_*/ |
リスト 7 は、LotteryFactory クラスの実装ファイルです。
リスト 7. LotteryFactory.cpp
#include "LotteryFactory.h"
#include "MegaLottery.h"
namespace lotto
{
LotteryFactory::LotteryFactory()
{
srand(time(NULL));
}
Lottery* LotteryFactory::getLottery(State s)
{
if (s == LotteryFactory::California)
{
Lottery* lotto = new MegaLottery(5,47,27);
return lotto;
}
else
{
Lottery* lotto = new Lottery(6,53);
return lotto;
}
}
LotteryFactory* LotteryFactory::getInstance()
{
static LotteryFactory instance;
return &instance;
}
} |
LotteryFactory には異なるタイプの宝くじが列挙されます。上記の例では Florida とCalifornia しか入れていませんが、必要な数だけ追加するのもわけありません。LotteryFactoryのコンストラクターは、lottery クラスが使用する rand() 関数をシードとして指定します。あとは、実行可能ファイルの main メソッドを実装するだけです。
リスト 8. Main.cpp
#include <iostream>
#include "LotteryFactory.h"
using namespace lotto;
int main()
{
LotteryFactory* factory = LotteryFactory::getInstance();
cout << "What lottery do you want to play?" << endl;
cout << "(1) California, (2) Florida" << endl;
int cmd;
scanf("%d", &cmd);
Lottery* lotto = 0;
switch (cmd)
{
case 1 :
lotto = factory->getLottery(LotteryFactory::California);
break;
case 2 :
lotto = factory->getLottery(LotteryFactory::Florida);
break;
default :
cout << "Sorry didn't understand that" << endl;
}
cout << "Ticket: " << lotto->printTicket() << endl;
delete lotto;
return 0;
} |
プログラムの実行
プログラムを実行する準備ができました。Run > Run を選択してください。
図 14. 基底クラスの選択
C/C++ Local Application を選択して New ボタンをクリックします。
図 15. 新規 C/C++ 実行プロファイル
Lottery プロジェクトに対応した実行構成の作成インターフェースが表示されます。このプロジェクトの実行可能ファイルを選択するため、Search Project ボタンをクリックします。
図 16. プロジェクト実行可能ファイルの検索
Eclipse によって作成されたバイナリーを選択して OK をクリックします。
図 17. プロジェクト実行可能ファイルの検索
Run をクリックすると、プログラムがコンソールで実行されます。以下のコードは出力例です。
What lottery do you want to play?
(1) California, (2) Florida
2
Ticket: 12 28 24 15 35 22 |
プログラムのデバッグ
このプログラムは問題なく実行されるはずですが、アプリケーションのデバッグ方法について説明しておきます。まず、コードにブレークポイントを作成します。それには行を選び、その横で右クリックしてToggle Breakpoint を選択します。
図 18. ブレークポイントの作成
実行構成を作成したときと同様に、デバッグ構成を作成する必要があります。Run > Debug を選択してください。
図 19. デバッグ構成の作成
上記の操作で表示されるデバッグ構成は実行構成に基づいているので何も変更する必要はありません。そのまま Debug をクリックします。
図 20. デバッグ構成
デバッガーが起動すると、デバッガー・パースペクティブに切り替えるよう求めるプロンプトが表示されるので、このプロンプトに従います。この構成では、main
メソッドの開始時に自動的にブレークするように設定したことに注意してください。そのためデバッガーは実行後すぐに中断され、図 21 のような画面が表示されます。
図 21. デバッガー
まとめ
この記事では宝くじのアプリケーションをビルドしてデバッグしました。宝くじの方式は簡単に追加することができます。一部の方式にはサブクラスが必要になることもありますが、CDT
では今まで以上に簡単にクラスとクラス階層を作成し、アプリケーションを実行、デバッグしてテストすることができます。
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | |  | Michael Galpin は、1998年からプロとして Web アプリケーションの開発に取り組んでいます。彼は、カリフォルニア州サンノゼにある eBay のソフトウェア・エンジニアです。California Institute of Technology で数学の学位を取得しました。 |
記事の評価
|