質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

675閲覧

C++において、初期化子の値をチェックしNGであれば例外を送出しているがその例外をcatchできない

ap2c9w

総合スコア40

例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/12/30 06:08

以下のソースにおいて、メンバ変数grade_が1未満であった場合に、例外を送出し、Formクラスをインスタンス化しないようにしたいのですが、(おそらく)throwをcatchできず、

terminate called after throwing an instance of 'std::runtime_error' what(): Grade Error [1] 780 abort (core dumped) ./a.out

となってしまいます。
どのようにすれば、所望の動作ができるでしょうか。
よろしくお願いいたします。

[Form.hpp]

c++

1#ifndef FORM_HPP 2# define FORM_HPP 3 4# include <iostream> 5# include <string> 6 7class Form 8{ 9public: 10 Form(int grade); 11 virtual ~Form(); 12 int validateGrade(int grade) const; 13private: 14 Form(); 15 const int grade_; 16}; 17 18#endif

[Form.cpp]

c++

1#include "Form.hpp" 2 3Form::Form() : grade_(1) {} 4 5int Form::validateGrade(int grade) const 6{ 7 if (grade < 1) 8 { 9 throw std::runtime_error("Grade Error"); 10 } 11 return (grade); 12} 13 14Form::Form(int grade) 15try 16 : grade_(validateGrade(grade)) 17{ 18 std::cout << "Form Name constructor called" << std::endl; 19} 20catch (...) 21{ 22 std::cout << "Form Name constructor call Failed" << std::endl; 23} 24 25Form::~Form() 26{ 27 std::cout << "Form Destructor called" << std::endl; 28}

[main.cpp]

C++

1#include "Form.hpp" 2 3int main(void) 4{ 5 Form* form001 = new Form(1); 6 delete form001; 7 8 Form* form002 = new Form(0); 9 10 return 0; 11}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

...こんなのがお望みか?

C++

1// Form.cpp 2#include "Form.hpp" 3 4Form::Form() : grade_(1) {} 5 6int Form::validateGrade(int grade) const 7{ 8 if (grade < 1) 9 { 10 throw std::runtime_error("Grade Error"); 11 } 12 return (grade); 13} 14 15Form::Form(int grade) 16try 17 : grade_(validateGrade(grade)) 18{ 19 std::cout << "Form Name constructor called" << std::endl; 20} 21catch (...) 22{ 23 std::cout << "Form Name constructor call Failed" << std::endl; 24 throw; // <------ [追加] 25} 26 27Form::~Form() 28{ 29 std::cout << "Form Destructor called" << std::endl; 30}

C++

1// main.cpp 2#include <iostream> 3#include <stdexcept> 4 5#include "Form.hpp" 6 7int main(void) try { 8 Form* form001 = new Form(1); 9 delete form001; 10 11 Form* form002 = new Form(0); 12 13 return 0; 14} catch (std::exception& ex) { 15 std::cerr << "exception caught in main: " << ex.what(); 16}

実行結果:

Form Name constructor called Form Destructor called Form Name constructor call Failed exception caught in main: Grade Error <--- mainでcatch できた♪

投稿2020/12/30 07:15

episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ap2c9w

2020/12/30 07:48

回答ありがとうございます! Form.cppに追加頂いた throw; // <------ [追加] がなくても、実行結果が同じになる…つまり、int Form::validateGrade(int grade) const{}で投げられたthrowが、Form::Form(int grade{}のcatchでも、int main(void) try {}のcatchでもcatchされることを確認しました。 Form::Form(int grade{}のcatchで、throwをcatchしているのに、int main(void) try {}のcatchがないと、terminate called after throwing an instance of 'std::runtime_error'となってしまう理由はわかりますでしょうか。 ※自分は、throwされた例外がcatchされたら、そこでその例外は処理される…と思っていましたので、int main(void) try {}でcatchするには、回答頂いたように、Form::Form(int grade){}のcatchでもthrowが必要であると思っておりました。
SaitoAtsushi

2020/12/30 08:04

コンストラクタの function try block は暗黙に例外を再送出します。 コンストラクタの中で例外が発生した場合にはそのオブジェクトは正しく構築できている保証がありません。 catch でなんとかして例外を外に見せないということは出来ません。
episteme

2020/12/30 09:27

ん? 例外を握りつぶしたかったの?
ap2c9w

2020/12/30 11:55

SaitoAtsushiさん ありがとうございます。納得いたしました。 暗黙の動作に自分で気がつくことができませんでした。 epistemeさん いえ、例外を握りつぶしたかったというわけではないです。 Form::validateGrade(int grade)でthrowした例外をForm::Form(int grade)のcatchでcatchしているはずなのに、なぜ、terminate called after throwing an instance of 'std::runtime_error'となるのかが知りたかったです。 SaitoAtsushiさんの回答より、コンストラクタの function try block は暗黙に例外を再送出するので、main()でもtry/catchが必要であることを理解いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問