を避けるスライスの例外の型(C++)
-
13-09-2019 - |
質問
私は設計例外階層のC++のための私の図書館があります。の"階層性"の4科目からstd::runtime_error.いうのは避ける スライスの問題 のための例外クラスでは、コピーコンストラクタを保護します。るのだそうgccが必要で、コピーコンストラクタを捨てる時に、インスタンスのようになり、苦情、保護コピーコンストラクタ.Visual C++8.0統一コードす。ある携帯へdefuseのスライスの問題のための例外クラス?は標準のもう何も言えるかどうかの実装が必要とすべきであるコピーコンストラクタのクラスがスローされ?
解決
いか設計例外階層なお図書館があります。をご利用 std::exception
階層として、 常に を導きだから例外がスローされる場合もその上位の階層となります。するための 外部のマーシャルClineのC++FAQ 読み込み FAQ17.6, 17.9, 17.10, は、 17.12 です。
として "強制ユーザーの獲による参照", わかんないのに良い方法はそれができていました。にっくにくいで遊んで(日曜日午後)に基づく 多様な投:
class foo_exception {
public:
explicit foo_exception(std::string msg_): m_msg(msg_) {}
virtual ~foo_exception() {}
virtual void raise() { throw *this; }
virtual std::string const& msg() const { return m_msg; }
protected:
foo_exception(foo_exception const& other): m_msg(other.m_msg) {}
private:
std::string m_msg;
};
class bar_exception: public foo_exception {
public:
explicit bar_exception(std::string msg_):
foo_exception(msg_), m_error_number(errno) {}
virtual void raise() { throw *this; }
int error_number() const { return m_error_number; }
protected:
bar_exception(bar_exception const& other):
foo_exception(other), m_error_number(other.m_error_number) {}
private:
int m_error_number;
};
の考え方は、コピーコンストラクタ保護が必要となる場合があり話 Class(args).raise()
の代わりに throw Class(args)
.ことができますげpolymorphicly行きた例外のユーザーにより能力が試されるよ。解決しようとする問題に最適な漁獲による価値 すべ お迎えする素敵なコンパイラの警告が表示されます。のようなもの:
foo.cpp:59:エラー:'bar_exception::bar_exception(const bar_exception&)'で保護されて
foo.cpp:103:エラー:このコンテキスト内で
もちろんのこによるものであり、価格にすることができるのでは用いられていない throw
明示的またはお迎えする同様のコンパイラの警告:
foo.cpp:関数'無効h()':
foo.cpp:31:エラー:'foo_exception::foo_exception(const foo_exception&)'で保護されて
foo.cpp:93:エラー:このコンテキスト内で
foo.cpp:31:エラー:'foo_exception::foo_exception(const foo_exception&)'で保護されて
foo.cpp:93:エラー:このコンテキスト内で
全体的に、かなコーディング基準及び文書を記述しなければなりません捕ます。いかご確認ください図書館を捕る例外での取扱基準および投げの新鮮なオブジェクト(例、 throw Class(constructorArgs)
または throw;
).私は期待その他のC++プログラマーと同等の知識が追載の書類だけでした。
他のヒント
あなたの例外は、パブリックコピーコンストラクタを持っている必要があります。コンパイラが動作するように、例外処理のためにそれを周りにコピーできるようにしています。
あなたの問題を解決するには、常にその代わり、参照によってキャッチすることです
try {
// some code...
throw MyException("lp0 is on fire!");
} catch (MyException const &ex) {
// handle exception
}
(const
ネスはオプションですが、例外オブジェクトを変更する必要はほとんどありませんので、私はいつもそれを置く。)
トーマスの答えは正しいですが、私はまた、あなたが「例外階層を設計する」ことにより、あなたの時間を無駄にしないお勧めしたいと思います。設計のクラス階層は、あなたは、単にC ++標準の例外クラスから新しい例外タイプのカップル(およびそれを超えない)を導き出すことができ、特にとき、特に悪い考えです。
の携帯の方法は、思った停止のお客様の図書館からの例外を捕捉正しく価値
- 例外をスローから 仮想上げ 方法の例外クラスは、コピーコンストラクタを保護します。(感謝D.Shawley)
- スロー由来のものから例外がスローされる場合は、図書館や公開例外の基底クラスのお客様にすることができました。ベースの授業はとて保護コピーコンストラクタは、できる良い方法を捕ます。(記 こちらの のためのsimmilar問)
のC++の標準的な状態でコピーコンストラクタが必要でアクセス可能なように投げる.Visual C++8.0私の設定に違反しこの部分の標準的な強制の存在にコピーコンストラクタです。第15.1.3:
う表現を初期化し、一時オブジェクトの種類によって決定されるを取り除く際はトップレベルのcv-予選から静的タイプのオペランドのスローするように調整するタイプから"配列のT"または"機能を返T"は"ポインタを"または"ポインタ機能を返T"です。
の利用の一時オブジェクトを排除することができな変化を意味するプログラムの実行コンストラクタおよびdestructorsの使用に伴う一時オブジェクト(12.2)、その例外でのハンドラの初期化することができ、引数のスロー表現です。場合にスローされオブジェクトはクラスオブジェクトのコピーコンストラクタを初期化するために使われます。一時的なコピーにアクセスすることはできませんのプログラムは虐待を形成する際の一時オブジェクトがその排除すること)
この回答が投稿したOPうにし、除去してから質問を掲載しています。
私はC ++例外コードで構築されたのいずれかを使用しないように言うだろう。あなたは例外を持たなければならない場合は、最初から独自に作成します。それは、彼らが同様おろか同様の方法で実装すること、およびC ++で例外の実装鈍いように振る舞う必ずする唯一の方法なのは無能である。