Namaran

Code daily. Without assist.

2026-09-21

percentage.cpp

#include <iostream>
#include <stdexcept>

class Percentage {
public:
    explicit Percentage(int value) : value_(value) {
        if (value < 0 || value > 100) {
            throw std::invalid_argument("out of range");
        }
    }
    int value() const { return value_; }
private:
    int value_;
};

int main() {
    try {
        Percentage p1(50);
        Percentage p2(150);
        std::cout << p1.value() << " " << p2.value() << "\n";
    } catch (const std::invalid_argument &e) {
        std::cout << "caught: " << e.what() << "\n";
    }
}

このコードは何を出力するでしょうか?

Answer

caught: out of range(その後に改行)。Percentage0以上100以下という不変条件をコンストラクタの中で検査しており、外れていれば例外を投げます。p1の構築は成功しますが、続くp2(150)の構築中に例外が投げられます。コンストラクタが例外を投げると、そのオブジェクトは(部分的にも)存在しなかったことになり、tryブロックの残り(p1.value()p2.value()を含むstd::coutの行)は実行されずにcatch節へ制御が移ります。すでに構築済みのp1は、この巻き戻しの過程で通常どおりデストラクタが呼ばれて破棄されます。「不変条件を型で守る」とは、この例のように、不変条件を満たさないオブジェクトをそもそも存在させない(構築自体を失敗させる)ことで、以降そのクラスの値を使うコードが常に不変条件を前提にできるようにする設計です。