【A4】C++テクニカルセッション「暴れん坊のC++をどう使いこなすか」
多人数開発現場におけるC++言語の活用の問題点と対策
Java読書会 代表
高橋 徹 （torutk@02.246.ne.jp）

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

1

暴れん坊のC++ アジェンダ• 発表者とJava読書会とC++• 暴れん坊C++の姿• 暴れん坊C++に蹂躙される開発現場• 暴れん坊C++の押さえどころ• まとめ

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

2

1

発表者とJava読書会とC++
発表者のC++との出会いと関わり
Java読書会について本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

3

発表者略歴
• C++との出会い• 1991年、学生時代にファーストコンタクト• それまでは、Basic、アセンブラ、C言語、Pascal言語に触った経験のみでオブジェクト指向プログラミング言語は初• 就職後、仕事としては• Java言語中心（20世紀）• C++言語中心（21世紀）• 大規模なソフトウェア開発プロジェクトをサブリーダークラスの役割で転々としており、自分でコードを書くことはほとんどない• 会社とは別に技術活動• 個人Webページで技術発信（http://www.02.246.ne.jp/~torutk/）• Java読書会
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

42

Java読書会• 活動概要• 東京近郊でJavaに関する技術書籍を読む会を開催• 1998年12月より現在に至るまで毎月1回土曜日開催「いい本があるが、独りで読むのは難しい」が発端• 毎回十数人参加• 仕事でJavaを使っていない人もある程度の割合で参加→ C++技術ネタで盛り上がることがしばしばURL
http://www.javareading.com/bof/
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

5

暴れん坊のC++の姿
C++言語の特徴
C++言語の難しいところ
C++言語の学習

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

63

暴れん坊のC++の姿

メモリ管理• C++超簡略歴史

ポインタと参照とスタックとヒープ

例外• 1983年「C++」命名• 1990年ARM出版

const• 1998年ANSI/ISO標準化• C++の今テンプレート

効率的な使用方法の蓄積が進んでいる

STL

C++

• 標準化対応がひと段落し、• 進歩的な使い方が提唱されている

演算子オー
バーロード

（テンプレート・メタプログラミング）

クラスと継承IOストリーム

ジェネリックス・プログラミング
7

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

暴れん坊C++の姿• C++言語の習得でぶつかったこと• 実体（スタック）とポインタと参照の使い分け• コピーと代入を自前で定義するクラス• constの記述がよくわからない• STLのコンテナ・イテレータは複雑C++• テンプレートは難関

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

84

暴れん坊C++の姿• C++言語の学習• 15年間経っても熟練には程遠い発表者• これを読めばという定番の書籍が見当たらない• 「Effective C++」は最近読める知識レベルに達したと思う→ 初心者に薦められる本ではない。

• 独学には難しい言語ではないか• やさしいコミュニティがあればいいな

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

C++

9

暴れん坊C++に蹂躙される開発現場
少人数・小規模な開発ではほとんど問題にならないが、多人数・大規模開発で発生する困難な問題がある。

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

105

暴れん坊C++に蹂躙される現場• 想定する開発現場• 開発人数： 10人以上• 開発規模： 十万行以上• 開発期間： 数ヶ月以上• プラットフォーム： Windows, UNIX系混在• 開発言語： C++言語

11

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

暴れん坊C++に蹂躙される現場• 多人数開発で起きる問題• プログラマの技量によるコード・品質のばらつき• コンパイル・リンク時間の増大• 名前の衝突• ライブラリ分割の問題

C++• 同じクラスが異なるライブラリに重複• ソースコードのディレクトリ構造

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

126

暴れん坊C++に蹂躙される現場• プログラマの技量によるコード・品質のばらつき• プログラマのC++知識の理解・使用レベルは揃っていない
C言語知識

better Cとして使用するレベル
配列・インデックス、C標準関数を使う

古典C++言語知識

クラスを中心に使用するレベル

標準C++言語知識

クラス・継承・集約、C標準+ iostreamを使う
クラスに加えSTL・テンプレートを使用するレベル

前衛C++言語知識

イテレータ、アルゴリズムを使う
テンプレートを駆使するレベル
他の知識レベルでは理解不能なコード13

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

暴れん坊C++に蹂躙される現場• プログラマの技量によるコード・品質のばらつき例）Sensor型オブジェクトを管理するデータ構造と処理の書きっぷ
りの違い
Sensor* sensors[MAX_NUM];:
for (int i=0; i<MAX_NUM; i++) {sensors[i]->update();}「古典C++言語知識」

vector<Sensor*> sensors;「標準C++言語知識」:
for (vector<Sensor*>::iterator it = sensors.begin(); it!=sensors.end(); ++it) {(*it)->update();}std::vector<Sensor*> sensors;「前衛C++言語知識」:
std::for_each(sensors.begin(), sensors.end(), std::mem_fun(&Sensor::update));
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

147

暴れん坊C++に蹂躙される現場• プログラマの技量によるコード・品質のばらつき例）数値型から文字列への変換処理の書きっぷりの違い「C言語知識」

int value = 12345;
char buffer[16];snprintf(buffer, 16, “%d”, value);「古典C++言語知識」

int value = 12345;
ostringstream os;os << value;
string str = os.str();「標準C++言語知識」(+Boost)int value = 12345;
string str = boost::lexical_cast<string>(value);

15

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

暴れん坊C++に蹂躙される現場•コンパイル・リンク時間の増大• コード規模が大きくなると指数的にビルド時間が増加する例） オープンソースのCORBA実装 ACE+TAO ( Ver.1.6.1) の場合
ACEのみ
ビルド時間
総行数
命令行数
ファイル数
クラス数0:10:40
307,819
79,9301,248841

ACE+TAO
合計
2:35:30
1,066,708
247,391
2,592
4,548

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

ビルドマシンのスペック•CPU: Athlon 64x2 4200+(2.2GHz)•Mem: 2GB (DDR2 800)
•HDD: SATA 1.5Gbps•OS: Windows Vista 64bit•C++: VC++ 9.0 (VS 2008)168

暴れん坊C++に蹂躙される現場• コンパイル・リンク時間の増大• 差分コンパイルは現実的ではない• C++はヘッダーファイルに実装細部を記述する（privateメンバー）– publicな部分に修正がなくても再コンパイルが必要• ヘッダーファイルが芋づる的に#includeされるため、広範囲に変更波及
project/+--- include|+--- Alfa.h|+--- Bravo.h|+--- Charlie.h+--- alfa|+--- Alfa.cpp+--- bravo|+--- Bravo.cpp+--- charlie+--- Charlie.cpp

Alfa.h → Bravo.h → Charlie.hのinclude関係があれば、Charlie.hを修正すると、Charlie.cppだけでなく、Bravo.cpp、Alfa.cppの再コンパイルも必要となる

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

17

暴れん坊C++に蹂躙される現場• 名前の衝突• クラス名、マクロ名、ファイル名が衝突し、一見不可解なコンパイルエラーが発生• ヘッダーファイルのinclude順番で挙動が変わる– 例） <winsock2.h>と<windows.h>• ヘッダーファイルがなぜか読み込まれない– 同じファイル名が複数存在した– インクルードガードが重なっていた

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

189

暴れん坊C++に蹂躙される現場• ライブラリ分割の問題• ライブラリ同士に相互依存や循環依存があると、ビルドが一筋縄ではいかない
alfa.lib

それぞれのライブラリ開発担当者には、相互依存の認識はほとんどないbravo.libcharlie.lib
delta.lib

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

19

暴れん坊C++に蹂躙される現場• 同じクラスが複数ライブラリに重複• 曖昧なパッケージ分割設計により、共通するクラスがあちこちのライブラリに含まれてしまう• クラスのstaticなデータがシステムで唯一とならない• #ifdefで異なるロジックがコーディングされていると、悲惨な状況に
alfa.libbravo.libclass One

class One

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

20

10

暴れん坊C++に蹂躙される現場• ソースコードのディレクトリ構造にも問題• ライブラリに関する問題の一因に、C/C++の伝統的なソースコードのディレクトリ構造がある
ディレクトリ分割なし

中途半端なサブディレクトリ化

project/+--include|+--Alfa.h|+--Bravo.h|+--Charlie.h+--src+--Alfa.cpp+--Bravo.cpp+--Charlie.cpp

project/+--include|:+--src+--alfa|+--Alfa.cpp+--bravo|+--Bravo.cpp+--charlie+--Charlie.cpp

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

21

暴れん坊C++の押さえどころ
プログラマの技量によるばらつきをおさえるパッケージ設計により設計段階からライブラリ化を考慮することで、ビルド問題、名前衝突問題、ライブラリ問題をおさえる本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

22

11

暴れん坊C++の押さえどころ• プログラマの技量のばらつきをおさえる• プロジェクトで使用するC++知識範囲を定義する• C++言語特徴のどの範囲を使用するか• ライブラリセットは何を使用するか• 型、マクロ、エラー処理、メモリ管理の方法はどうするか

プロジェクト言語の規定

23

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

暴れん坊C++の押さえどころ• プログラマの技量のばらつきをおさえる• 「プロジェクト言語」をコーディング規約で規定する• 使用するC++言語範囲を定める– 例外機構の使用有無– 多重継承の使用有無– STL、テンプレートの使用有無

等• 使用するライブラリセットを定める– OSのシステムコール使用有無– C標準関数の使用有無– C++標準クラスの使用有無– サードパーティライブラリの使用有無

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

2412

暴れん坊C++の押さえどころ• プログラマの技量のばらつきをおさえる• プログラマは規約範囲を理解し実践できる技量が必要• 理想はプロジェクトに参加する時点で不足知識のトレーニング実施– 定型の教育コースでは難しい– トレーナーになれるリーダー格プログラマは忙しい– 定番書籍もない （Effective C++は難しい）• 現実解としてプロジェクト参加のための課題を用意– ミニ機能を設計・実装させる– 添削・模範解答の提示と指導– 開発ルール・開発環境はプロジェクト基準を使用

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

25

暴れん坊C++の押さえどころ• コーディング規約参考• 書籍（日本語）• 「C++ Coding Standards – 101のルール、ガイドライン、ベストプラ
クティス」（H.Sutter、A.Alexandrescu著）• 「Effective C++ 第3版－プログラムとデザインを改良するための55項目」（S.Meyers著）• 「C++スタイルブック」（T.Misfeldt、G.Bumgardner、A.Gray著）• Web（英語）• “Applied Informatics C++ Coding Style Guide – Rules andRecommendations” (フレームワークPOCOの規約）• “Joint Strike Fighter Air Vechicle C++ Coding Standards”(ロッキード・マーチン社）

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

26

13

暴れん坊C++の押さえどころ• パッケージ設計の導入• C++はライブラリ化の機能はサポートしていない• OS／コンパイラ系に依存したライブラリの仕組みを使う– Windows： DLL– UNIX系： shared object (so)• 設計ルールでパッケージ設計を導入する• C++のnamespaceを使う• ヘッダーファイルの可視／非可視でパッケージアクセス制御– ディレクトリ構造上で可視／非可視を分ける

27

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

暴れん坊C++の押さえどころ• パッケージ設計の導入• パッケージはそれぞれ異なるnamespaceに置く• namespaceごとにヘッダーファイル・ソースファイルを格納するディレクトリを設ける
パッケージ”alfa”のディレクトリとproject/namespace+--alfa/|+--include/|+--src/+--bravo/|+--include/|+--src/+--charlie|+--include/|+--src/

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

namespace alfa {class Alfa {};}

28

14

暴れん坊C++の押さえどころ• パッケージ設計の導入• パッケージ外部から可視なヘッダーファイルと非可視なヘッダーファイルとを分離し、格納するディレクトリを分ける

project/+--alfa/+--include/| +--Alfa.h+--src/+--AlfaImpl.h+--Alfa.cpp+--AlfaImpl.cpp

エクスポートするヘッダーファイルのみ格納
エクスポートしないヘッダーファイルはソースファイルと一緒に格納

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

29

暴れん坊C++の押さえどころ•パッケージ設計の導入•

可視なヘッダーファイルから非可視なヘッダーファイルをincludeしない→ 絶縁設計を検討（書籍「大規模C++ソフトウェアデザイン」）•

継承よりコンポジション•

データメンバーは実体よりポインタ•

プロトコルクラス•完全絶縁具体クラス（pimplイディオム）•

コンポーネントラッパー

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

30

15

暴れん坊C++の押さえどころ• パッケージ設計の導入• プロトコルクラスの実装例（Javaのinterfaceによく似ている設計）#include <string>#include <boost/shared_ptr.hpp>
using std::string;using boost::shared_ptr;

・private/protectedメンバーなし
・純粋仮想関数・非インライン仮想デストラクタ
で定義する

namespace character {class Character {public:virtual ~Character();
virtual const string getName() const = 0;virtual void setName(const string& aName) = 0;
static shared_ptr<Character>create(const string& aName);};}実装はパッケージ外から非可視のクラスで提供するインスタンス生成は、別クラス、外部関数、静的関数等で実現

31

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

暴れん坊C++の押さえどころ• パッケージ設計の導入• パッケージ単位にライブラリをビルドする• ライブラリとエクスポートするヘッダーファイルだけを利用者へリリースする
project/+--alfa/+--lib/| +--alfa.dll+--include/| +--Alfa.h+--src/+--AlfaImpl.h+--Alfa.cpp+--AlfaImpl.cpp
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

alfaパッケージ利用者に提供する範囲
・ライブラリファイル
・可視なヘッダーファイル
利用者は、可視なヘッダーファイルが変更されなければ再コンパイル不要（ライブラリの差し換えで対応可能）3216

暴れん坊C++の押さえどころ• ビルドツール• 共通設定を一元化でき、一発操作でビルドできる、特定のIDEやプラットフォームに依存しないツールが理想• GNUmake : 記述が大変• Apache Ant ： Javaでは定番だが、C++適用ノウハウが少ない• 着目しているツールは• ACE+TAOのビルドツール MPC (MakeProjectCreator)• CMake

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

33

まとめ
多人数開発での問題の多くは、一見設計ではなく管理的な問題に見える。
しかし、管理的な問題を押さえるためには、設計から取り組む必要がある。

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

34

17