読者です 読者をやめる 読者になる 読者になる

@uents blog

Code wins arguments.

ロベールのC++入門講座でC++を初歩から入門する(1日目)

OpenCVだのOpenNIだのを勉強しようと思ったら、どうもC++を先に覚えた方が手っ取り早そうなことに気づく。というわけで、積ん読していたローベルのC++で勉強するよ。できれば、この3連休でひと通り読破したい!

1章 まずは使い方

各OS毎のC++の開発ツールを紹介。EclipseとかXcodeとかちゃんと使いこなせるようになりたいようななりたくないような(笑) 自分の場合はg++/emacsでとりあえずやるので、ほどほどに読み流す。
Makefile、そういえばいつも誰かのをコピペしてる。ちゃんと書けるようになりたい><


それはともかく、C++Hello Worldしてみる。

/**
 * @file Hello.cpp
 */
#include <iostream>
using namespace std;

int main() {
	cout << "Hello World" << endl;
	return 0;
}

なんだこの「<<」って。pipeみたいなもんか? using namespace で名前空間の記述を省略。文字列を確実に表示したい場合、改行がついてもいいならendlでよいが、改行をつけない場合はflushらしい。ほほう。
ところで、このmain()の後に改行を入れずに{を続けるスタイルって何スタイル? CにしろObjective-Cにしろ、普通は改行を入れて{な気がするので、個人的にはなかなか気持ち悪い。C++はこれが普通なのかな?

2章 計算してみよう

ここらへんの演算子やら条件文やらは、Cとだいたい同じなので、ざーっと斜め読み。分からんかったら戻ってくればいいし。

3章 ほんの少し深く

C++には「参照」というポインタのようなものがあるらしい。型名に&をつけるとそれになる。これは知らなかった。ポインタと何が違うんやろう?うーん、ちゃんと理解できてないかも。

数学関数はcmathをインクルードすればよい。math.hではないのね。stdlib.hならcstdlibだし、string.hならcstring。

オーバーロードの説明、分かりやすい。オーバーロードと言えばサブクラスがスーパークラスのメソッドを上書きするときに使うイメージだけど、普通の関数でもできちゃうのね。知らなかった。

bool型、便利だな。Cにも欲しい。C99にもあるんだっけ?

4章 ポインタ天国

Cではとにかく何をするにもポインタを使うことになる。なのでちゃんと理解できてるつもり。
この章ではポインタと配列の違いがとうとうと述べてあるが、ざっと読み飛ばす。

5章 クラスの前に

構造体の宣言には当然structがいるけど、宣言した型を使う場合はCみたくstruct xxxのようにstructをつける必要がない。

struct Student {
	char name[MAX_NAME+1];
	int scoreJapanese;
	int scoreMath;
	int scoreEnglish;
}

int main() {
	Student students[] = {
		{"Ichiro", 73, 98, 86,},
		{"Daisuke", 64, 45, 40,},
		{"Hideki", 76, 78, 69,},
	};

	return 0;
}

まあ、Cだとこういう場合、typedef struct { ... } Student だけど、この面倒なtypedefが要らないのはすばらしい。

デフォルト引数、他の言語にもだいたいあるけど、便利。

/**
 * @file Default1.cpp
 */
#include <iostream>
using namespace std;

void f(int a = 1, int b = 2) {
	cout << "a = " << a << ", b = " << b << endl;
}

int main() {
	f();    // a = 1, b = 2
	f(3);   // a = 3, b = 2
	f(5,6); // a = 5, b = 6
	return 0;
}

変数のスコープの考え方はCとほぼ一緒。基本的にはブロックに閉じる。
そういえば、C++はクラス変数をどう宣言するんだろう?Objective-Cにはクラス変数がないので、ファイル内の大域変数で代用するのが定石だったと思うけど、C++も同じかな。

メモリの獲得・解放はnew/deleteで行う。Cでいうmalloc/freeと同じだろうけど、malloc(sizeof(...))としなくていいのが便利。

/**
 * @file New1.cpp
 */
#include <iostream>
using namespace std;

int main() {
	int *p;

	p = new int;
	*p = 1;
	cout << *p << endl; // 1と表示
	delete p;

	return 0;
}

ところで、オブジェクトを生成するときに使うのがnewではないのかな?もしかするとpはintクラスのオブジェクト?いやそれは違うかな。
newとコンストラクタの違いは?あれ、Rubyとごっちゃになってる?あとで整理しよう…
ちなみにnewでメモリ獲得できなかった場合は、bad_allocという例外が発生するそう。


次は「6章 クラスの基礎」から。