独習C++ 第1章 C++の概要
はじめは
みたいなことが書いてある。ちゃっかり独習Cの宣伝もしてる。
あとはC++0xがどうとかこうとか。*1
1.1 オブジェクト指向プログラミングとは
カプセル化、ポリミーフィズム(関数のオーバーロードとか)、継承とか、Javaで似たようなことやったなーって感じだった。
関数のオーバーロードがめっちゃ便利そう。Cだと絶対値求めるのにint型だとabs()、long型だとlabs()、double型だとfabs()って使い分けないといけないけどC++だと全部abs()でOK。こういうのを関数のオーバーロード(多重定義?)っていうみたい。素晴らしい。(Javaでもあったけど使う機会がそんなになかった。)
1.3 C++のコンソール入出力
いよいよソースコードが出てきた。
って書いてある。Cでは
int a,b; scanf("%d %d",&a,&b); printf("%d %d\n",a,b);
って書いてたのを、C++では
int a,b; cin>>a>>b; cout<<a<<' '<<b<<endl;
って書くみたい。(この本ではendlじゃなくて\n使ってる。)
C++のcinとかcoutは型を指定しなくていいから楽っぽい。
Cのprintfみたいに表示する桁数の指定とかは載ってないから調べてみたら、std::setprecision()ってのを使うらしい。
C++ではcinとかcoutとかendlとか使うときは、
using namespace std;
って宣言しとかないとg++ではエラー出た。名前空間の話らしいけどここでは特に言及なかった。
1.4 C++のコンソール入出力
/* C++のコメントは、Cと同様に 複数行のコメントと、*/ // 単一行で書くコメントがあるよ
とのこと。Javaと混同してるのか、Cでも両方いけるのでは?とか思ってしまったけどダメらしい。
1.5 クラス
お待ちかねのクラス。こんな感じで宣言するらしい。
class ClassName { // 非公開の関数と変数を宣言 public: // 公開の関数と変数を宣言 } object-list;
object-listはあってもなくても。クラスの宣言内で宣言された変数とか関数のことをそれぞれメンバとかメンバ関数とか呼ぶらしい。
メンバって言葉もそうだし、宣言方法もも見た瞬間に構造体っぽいなーと思った。メンバへのアクセスもClassName.ob1みたいにドット使うし、関連に関しては、2章で説明がある。
Cの構造体と何が違うかって言うと、公開・非公開があるから、非公開のメンバにはドットを使って直接アクセスは出来ないところか。公開のメンバ関数を使う以外では値を変更できないみたい。
構造体の時もそうだったんだけど、最後のセミコロンを忘れそうで怖い。
メンバ関数の定義(例えば返り値をint型とする)は
int ClassName::foo() { // あれこれする }
というふうに、関数の名前の前に(クラス名)::を付けないといけない。
ここでは書いてないけど、名前空間に関連する話でクラスごとに名前がつけやすいようにしてあるみたい。
1.6 CとC++の相違点
- 関数の引数がないときにvoid書くとか冗長だしアホでしょ
- プロトタイプ宣言は必ずしろやゴルァ
- void以外で宣言した場合はreturn文で返り値返さないと変な動作するぞ!
- 変数の宣言がどこでもできる!ステキ!
- bool型で条件文を見やすくしておいてやったぞ
とか書いてある。
1.7 関数のオーバーロード
C++の機能でクラスの次に重要な機能は、おそらく関数を多重定義すること、つまり関数のオーバーロード(function overloading)でしょう。
(原文ママ)
つまり、
- 関数の中身(実際のプログラム)が違っても、同じ名前で関数の宣言ができる!
- 同じ機能を持つものは同じ書き方で呼び出せる!
- どの関数を使うかはコンパイラが勝手に判断してくれる!
便利!!!!!
1.1で述べた絶対値を求める関数での面倒臭さが解消されてる
ただし、コンパイラが判断できないようなもの(引数の型か引数の数が違わないもの)はオーバーロードできない。
オーバーロードできる例1
// 二乗する関数 square(x)=x*x int square(int x); long square(long x); double square(double x); // 引数の数は同じだが、引数の型が違うからOK
オーバーロードできる例2
// 平均を求める関数 Average int average(int a, int b); int average(int a, int b, int c); // 引数の型は同じだが、引数の数が違うからOK
オーバーロードできない例
// 文字列を数値に変換する関数 double atof(const char *s); int atoi(const char *s); long atol(const char *s); // 同じ機能を持つものは同じ書き方で呼び出したいが // これらは全て同じ型の引数を持つためNG
この場合はオーバーロードできない。
文字列の長さも一緒に呼び出して、なんとかオーバーロードできないかなーと考えたけど、文字列の長さはだいたい全部intで収まりそうだからやっぱり無理っぽい。