2016-04-18 7 views
7

はのは、私が派生クラスのコンストラクタでNoexcept約束:ベースコンストラクタで有望なnoexceptなしで使用できますか?

class C : public B { 
    public: 
    C() noexcept; 
} 

noexcept指定子は、基本クラスによって、同じ約束を必要としていたクラスがあるとしましょうか?つまり、noexceptの使用を検討しているときに、C :: C()の動作を調べるか、B :: B()が例外をスローするかどうかを検討する必要がありますか?

たとえば、B :: Bが例外をスローすると、それはC :: Cまたは新しいクラスインスタンスを要求していたコードに伝播しますか? - C :: Cに伝播すると、それが基底クラスがコンストラクタのnoexceptでない場合、コンストラクタのnoexceptを避ける理由の1つになります。

+0

ベースクラスの構築が失敗した場合、派生クラスの構築は成功しますか? –

+0

いいえ、コンパイラがこれをすべてまとめたとき、それはそれぞれのコンストラクタを独立して処理しますか?つまり、派生クラスのnoexcept仕様はコンパイラが基本コンストラクタをどのように管理するかに影響しませんか? – rsjaffe

+0

実際、私の質問は誤解を招くかもしれないと思います。あなたのベースクラスが 'vector'で、サイズをゼロにすると例外がスローされないことを実際に保証することができます。同様に、 'noexcept'は何かが投げられてはならないことを意味します。' abort() '(私はドキュメントを参照してください)が呼び出されないようにします。したがって、ベースコンストラクタが 'noexcept'ではない場合は、' try' - 'catch'でラップする必要がありますが、' noexcept'保証を満たすことができます。 –

答えて

6

基本クラスのコンストラクタをnoexceptとして宣言する必要はありませんが、noexceptとして宣言されている派生コンストラクタによって呼び出された場合はスローしないでください。

はい、ベースクラスのコンストラクタが(例外などの理由で)スローする可能性があるかどうかを検討する必要があります。

私の質問には、次の例外がありますか?

コールがこのような流れ:サブオブジェクト(それはベースまたはメンバーであるかどうか)コンストラクタがスローした場合

caller 
    -> derived constructor (the noexcept applies to this) 
    -> subobject constructors (includes bases) 
    - derived constructor body (not a call, but part of the derived constructor that is executed after the subobjects are constructed) 

だから、それは最初のない由来のコンストラクタ、に行くと††は、コンストラクターがnoexceptでなかった場合、呼び出し元に伝播するように例外を呑み込むことはできません。しかしそれ以来、std::terminateが呼び出されます。

派生によって、それは要件を満たしていないし、そうしないrarly理由があるので、それ自体がnoexceptを宣言することができ、必要に応じてベースが実際に投げていない場合は†。おそらく、基本クラスがC++ 03をサポートしなければならないライブラリの一部である場合、派生クラスは後の標準を引き継ぐかもしれませんが、それは理にかなっています。

†† function-try-blockでキャッチすることはできますが、それらは常に再びスローされます。

+1

'C'のctorで関数のtry-blockを使って良いエラーメッセージを出力することができます(プログラムを中止するためには続ける必要がありますが、復旧する方法はありません)。 –

+0

@ M.Mああ、忘れました。私は私の答えにメモを付けました。 – user2079303