[C++] クラスについて
目次
江添本 18章 p.221~
変数をまとめる
2次元座標の点を表すPointクラスを考える
struct Point {
// x, y: データメンバー
int x;
int y;
};
Point p1;
p1.x = 2;
p1.y = 3;
// Point p1 {2, 3}; とかいても初期化できる
まとめた変数に関数(機能)をつける
分子と分母からなる分数クラス(Fractional)を考える
struct Fractional {
int num;
int denom;
};
fractional x{1, 2};
scd::cout << static_cast<double>(x.num) / static_cast<double>(x.denom);
割り算の処理をクラスに紐づく関数(メンバー関数)にまとめる
struct Fractional {
int num;
int denom;
double value() {
return static_cast<double>(x.num) / static_cast<double>(x.denom);
}
};
fractional x{1, 2};
std::cout << x.value();
メンバー関数はデータメンバを変更することもできる
sturct X {
int data;
void f() {
data = 3;
}
};
分数クラスにセッターを定義してみる
struct Fractional {
int num;
int denom;
void set(int num_) {
num = num_;
denom = 1;
}
void set(int num_, int denom_) {
num = num_;
denom = denom_;
}
}
fractional x;
x.set(5); // num: 5, denom: 1
x.set(2, 3); // num: 2, denom: 3
データメンバーとセッターの引数の名前が衝突するとどうなるか
struct S {
int x;
void f(int x) {
x = x;
}
};
S s{0};
s.f(1);
std::cout << s.x; // 0が出力される
メンバ関数内のxは引数のxであるから
クラスもスコープを持つ
int x; // グローバル名前空間スコープ
struct S {
int x; // クラススコープ
void f(int x) {
x = x; // 関数のブロックスコープ
}
}
内側のスコープは外側のスコープを隠す
→ クラススコープはグローバル名前空間スコープを隠す
→ 関数ブロックスコープはクラススコープを隠す
名前がどのスコープに属するかを明示的に指定することによって隠された名前を使うことができる
int x;
struct S {
int x;
void f(int x) {
x = 0; // 関数のブロックスコープのx(引数のx)に0を代入
S::x = 0; // クラススコープのx(データメンバーのx)に0を代入
::x = 0; // グローバル名前空間スコープのxに0を代入
}
}
- 名前空間スコープ
- namespace_name::name
- クラススコープ
- class_name::name