第29回 確認問題(クラス基本)
STEP 4 で扱った class / メンバ関数 / this / static / 演算子オーバーロード の総合確認クイズ。全 12 問、カテゴリ別採点。
進め方
- 各問題に答えると即座に正誤と解説が表示されます
- 全問終えると下に総合結果が出ます。8 問以上正解で STEP 5 へ進める状態
- STEP 5 は本サイトの目玉「ライフサイクル編」。コンストラクタ/ムーブ/RAII を扱います
class
class と struct
0 / 3
Q1 class と struct の違いは?
class は継承できるが struct はできない
class はメンバ関数を持てる
機能にまったく違いはない(完全に同じ)
既定のアクセス制御だけ違う(class は private、struct は public)
C++ では両者ほぼ同じ機能。唯一の違いは既定のアクセス制御。どちらもメンバ関数、継承、アクセス指定子が使えます。
Q2 class Foo { int x; }; としたとき、インスタンス f から f.x にアクセスできる?
できる
できない(class の既定は private)
警告が出るが動く
x が public だけできる
class はアクセス指定子を書かないと既定が private。f.x は外からアクセスできません。struct なら既定 public で触れます。
Q3 「3D 座標を保持するだけ」のシンプルなデータ型、最も自然な書き方は?
class Vec3 { double x, y, z; };
struct Vec3 { double x, y, z; };
std::array<double, 3>
std::tuple<double, double, double>
データだけを持つ集約型は struct が慣習。全部 public で済み、意図が明確。①は全部 private になり使い物にならない。③④は型名が x/y/z と関連付けられていない。
member
メンバ関数と const
0 / 3
Q4 メンバ関数末尾の const の意味は?
戻り値が const になる
引数が const になる
この関数内でメンバ変数を書き換えない宣言
この関数がスレッドセーフになる
関数末尾の const は「this が指すオブジェクトを変更しない」という宣言。コンパイラがメンバ書き換えを検出してエラーにしてくれます。
Q5 const User& u から u.set_name("Bob")(非 const メンバ関数)を呼ぶとどうなる?
OK だが警告
コンパイルエラー
実行時エラー
名前は変わらないが通る
const オブジェクトからは const メンバ関数しか呼べません。これが「読むだけの関数には const を付ける」べき理由。
Q6 クラス内に定義したメンバ関数は暗黙的にどうなる?
const になる
virtual になる
inline になる
static になる
クラス内定義のメンバ関数は暗黙 inline。ODR(One Definition Rule)を気にせずヘッダに書けるのはこのため。
this/static
this と static
0 / 3
Q7 this が使えないのは?
非 const メンバ関数の中
const メンバ関数の中
コンストラクタの中
static メンバ関数の中
static メンバ関数は特定のオブジェクトに紐付かないため、this を持ちません。
Q8 次のコードの出力は?
class C { static inline int n_ = 0; public: C(){ ++n_; } static int n(){ return n_; } };
C a, b, c; std::cout << C::n();
0
3
1
コンパイルエラー
static メンバ n_ はクラスに 1 つだけ。3 回コンストラクタが呼ばれて 3 になる。
Q9 メソッドチェーン obj.f().g() を実現するため、f は何を返せばいい?
void
*this(自分自身への参照)
this(ポインタ)
新しいオブジェクト
メソッドチェーンには自分自身の参照を返すのが定石。return *this;。
operator
演算子オーバーロード
0 / 3
Q10 a + b という式は実際に何を呼ぶ?
add(a, b)
a.add(b)
a.operator+(b) または operator+(a, b)
plus(a, b)
演算子の正体は「関数名が記号の関数」。+ は operator+。メンバか非メンバで呼び出し形式が変わります。
Q11 std::cout << obj を使えるようにしたい。どう書く?
メンバ関数 operator<<
メンバ関数 operator>>
非メンバ関数 std::ostream& operator<<(std::ostream&, const T&)
virtual 関数 print
operator<< は左辺が std::ostream なので、メンバ関数としては追加不可。必ず非メンバで書き、std::ostream& を返してチェーンを可能にします。
Q12 + と += を両方実装する場合、推奨される実装順は?
+ を先に、+= は + を使って実装
+= を先に、+ は += を使って実装
両方独立に書く
+= だけ書けば + は自動生成される
+= を基礎に + を実装するのが定石。Vec operator+(Vec a, const Vec& b) { a += b; return a; }。これで挙動の一致と重複削減が両立します。