【C++言語入門】 第15回 例外-続き


,お願いするのだ
メソッドでも例外は使えます
CircleクラスにTestメソッドを追加し、その中から 例外 を投げてみますわ
#pragma once
#ifndef CIRCLE_H
#define CIRCLE_H
#include <iostream>
#include <stdexcept>
const double kPI = 3.14159265358979323846;
/// @brief 円
class Circle {
double diameter_; // 直径
public:
Circle(double diameter) : diameter_(diameter) {}
~Circle() {};
double Diameter() { return diameter_; }
void Diameter(double diameter) { diameter_ = diameter; }
virtual double Area() {
double radius = Diameter() / 2.0;
double a = radius * radius * kPI;
return a;
}
virtual void Test() {
std::cout << "例外を投げます" << std::endl;
throw std::exception("クラスのメソッドからの例外です");
return;
}
};
#endif // CIRCLE_H
#include <iostream>
#include <stdexcept>
#include "circle.h"
int main(int argc, char* argv[]) {
try {
Circle c(10.0);
c.Test();
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
return 0;
}

Testメソッドから投げられた 例外 をメイン関数内のcatchでしっかりと捕捉していますわ
コンストラクタでも例外を投げられますよ
Circleクラスのコンストラクタから 例外 を投げてみますわ
#pragma once
#ifndef CIRCLE_H
#define CIRCLE_H
#include <iostream>
#include <stdexcept>
const double kPI = 3.14159265358979323846;
/// @brief 円
class Circle {
double diameter_; // 直径
public:
Circle(double diameter) : diameter_(diameter) {
std::cout << "例外を投げます" << std::endl;
throw std::exception("コンストラクタからの例外です");
}
~Circle() {};
double Diameter() { return diameter_; }
void Diameter(double diameter) { diameter_ = diameter; }
virtual double Area() {
double radius = Diameter() / 2.0;
double a = radius * radius * kPI;
return a;
}
};
#endif // CIRCLE_H
#include "circle.h"
int main(int argc, char* argv[]) {
try {
Circle c(10.0);
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
return 0;
}

Circleクラスのインスタンスを生成しているだけなのだ
catchで捕捉されていますわ
デストラクタでは例外を投げられません
Circleクラスのデストラクタから 例外 を投げてみますわ
#pragma once
#ifndef CIRCLE_H
#define CIRCLE_H
#include <iostream>
#include <stdexcept>
const double kPI = 3.14159265358979323846;
/// @brief 円
class Circle {
double diameter_; // 直径
public:
Circle(double diameter) : diameter_(diameter) {
}
~Circle() {
std::cout << "例外を投げます" << std::endl;
throw std::exception("デストラクタからの例外です");
};
double Diameter() { return diameter_; }
void Diameter(double diameter) { diameter_ = diameter; }
virtual double Area() {
double radius = Diameter() / 2.0;
double a = radius * radius * kPI;
return a;
}
};
#endif // CIRCLE_H
#include "circle.h"
int main(int argc, char* argv[]) {
try {
Circle c(10.0);
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
return 0;
}


catchによる捕捉をおこなって、処理を完結しますわ
catchで捕捉するだけで、そのまま何もしないというのも選択肢ですわね
例外を再スローします
catchで捕捉した後、状況によって受け取った 例外 を再度投げることはできるのか?
#include <iostream>
#include <stdexcept>
void Test() {
try {
std::cout << "例外を投げます" << std::endl;
throw std::exception("例外が投げられました");
} catch (const std::exception&) {
std::cout << "例外を捕捉しました" << std::endl;
throw;
}
}
int main(int argc, char* argv[]) {
try {
Test();
} catch (const std::exception& e) {
std::cout << "メイン関数で例外を捕捉しました" << std::endl;
std::cout << e.what() << std::endl;
}
return 0;
}

Test関数内で投げられた 例外 は、Test関数内でcatchにより捕捉されますわ
throw;により捕捉された 例外 が再度投げられていますわ
Test関数内のcatchでは、処理に 例外オブジェクト を使用していませんので、オブジェクト名を省略していますわ
throwに対象のオブジェクトを指定する必要はありませんわ
例外処理から別のオブジェクトを投げる
catchの中から、捕捉した 例外 を投げることはできましたわ
#include <iostream>
#include <stdexcept>
void Test() {
try {
std::cout << "例外を投げます" << std::endl;
throw std::exception("例外が投げられました");
} catch (const std::exception&) {
std::cout << "例外を捕捉しました" << std::endl;
throw "文字列のオブジェクト";
}
}
int main(int argc, char* argv[]) {
try {
Test();
} catch (const std::exception& e) {
std::cout << "メイン関数で例外を捕捉しました" << std::endl;
std::cout << e.what() << std::endl;
} catch (const char str[]) {
std::cout << str << std::endl;
}
return 0;
}

Test関数内のcatchで 例外 を捕捉した後、文字列を 例外オブジェクト として投げていますわ
exceptionクラスのインスタンス以外に文字列オブジェクトをcatchするように追加していますわ
Test関数からは文字列の 例外オブジェクト が投げられるので、文字列の 例外オブジェクト を捕捉するcatchの部分が処理されますわ
Discussion