2017-12-07 14 views
0

例外を含むこのC++コードを分析する必要がありますが、私はどのコードが行うべきかを分析することに慣れていません。私が理解していないいくつかのことがあります。さらに、バッファデータ構造やC++で例外をスローする詳細についての経験はありません。コンストラクタと先進的な例外投げC++

データ構造の最大サイズはどれくらいですか? Seq_Bufferがsize_ = 100で作​​られている場合、と言うことです

  • は、どのように多くの 要素を保存することができますか?
  • 私の直感によれば、サイズ100のものを作成した場合、 の最大サイズは100になりますが、事実はわかりません。

コンストラクタはC++で例外をスローできますか?

  • Seq_Bufferのコンストラクタは例外をスローできますか?
  • これが本当であると仮定すると、なぜtry、catch、またはthrowブロックを指定した を説明せずに動作しますか?それが例外を得る唯一の方法だと思った

私はこれらの2つの質問を検索しようとしましたが、私は本当にかなり失われています。読んでいただきありがとうございます。私はこれらの2つの質問を検索しようとしましたが、私は本当に失われています。読んでいただきありがとうございます。

そのコンストラクタとSeq_Bufferクラスのコードは以下の通りです:

#ifndef SEQBUFFER_H 
#define SEQBUFFER_H 

#include <memory> 
#include <experimental/optional> 

#include "optional.h" 

// Exceptions classes 
struct full_buffer {}; 
struct empty_buffer {}; 

// Sequential buffer for values of type T 
template <typename T> 
class seq_buffer { 
public: 
    // Constructs a buffer for n elements 
    seq_buffer(int n) : 
    size_{n}, 
    buf_{new item_type[size_]} 
    { 
    } 

    // Default destructor 
    ~seq_buffer() = default; 

    // Size of buffer 
    int size() const noexcept { 
    return size_; 
    } 

    // Is buffer empty? 
    bool empty() const noexcept { 
    return next_read_ == next_write_; 
    } 

    // Is buffer full? 
    bool full() const noexcept { 
    const int next = next_position(next_write_); 
    return next == next_read_; 
    } 

    // Put element x into buffer with marker last. 
    // An empty element signals end of buffer. 
    void put(const optional<T> & x); 

    // Gets a pair with next element and last indication. 
    // Pair is accessed through members first and second 
    optional<T> get(); 

private: 
    // Compute next position after p following circular order 
    int next_position(int p) const noexcept { 
    return p + ((p+1>=size_)?(1-size_):1); 
    } 

private: 
    // Size of buffer 
    const int size_; 

    using item_type = optional<T>; 

    // Unique pointer to buffer of size_ elements. 
    std::unique_ptr<item_type[]> buf_; 

    // Next position to read 
    int next_read_ = 0; 

    // Next position to write 
    int next_write_ = 0; 
}; 

template <typename T> 
void seq_buffer<T>::put(const optional<T> & x) 
{ 
    const int next = next_position(next_write_); 
    if (next == next_read_) throw full_buffer{}; 
    if (!x) { 
    buf_[next_write_] = {}; 
    } 
    else { 
    buf_[next_write_] = *x; 
    } 
    next_write_ = next; 
} 

template <typename T> 
optional<T> seq_buffer<T>::get() 
{ 
    if (empty()) throw empty_buffer{}; 
    auto res = buf_[next_read_]; 
    next_read_ = next_position(next_read_); 
    return res; 
} 

#endif 
+1

コードを読んでもうまくいかない場合は、デバッガでテストケースを作成してください(そして、精神的にこれを行うことができる時間があります)それなしでコンストラクタにスローを入れて何が起こるかを見ることもできます – UKMonkey

+1

コンストラクタはメモリ不足のときに 'bad_alloc'を送出する' new'を使います。未知の型 'item_type'のオブジェクトも構築します。そのコンストラクタは、例外をスローする可能性もあります。 –

+0

私はこれが学生家庭仕事だと思います。 Raymond Jones、あなたはStroustrupの本の1つを読んでください。これはおそらくC++を学ぶ最良の方法です。 – Oliv

答えて

1

はい、私たちはconstructors.Itからの例外をスローすることができ、このコード例error.Takeコンストラクタ障害やクラスの初期化に対処する最善の方法でありますここで

class bar 
{ 
public: 
    bar() 
    { 
    std::cout << "bar() called" << std::endl; 
    } 

    ~bar() 
    { 
    std::cout << "~bar() called" << std::endl; 

    } 
}; 
class foo 
{ 
public: 
    foo() 
    : b(new bar()) 
    { 
    std::cout << "foo() called" << std::endl; 
    throw "throw something"; 
    } 

    ~foo() 
    { 
    delete b; 
    std::cout << "~foo() called" << std::endl; 
    } 

private: 
    bar *b; 
}; 


int main(void) 
{ 
    try { 
    std::cout << "heap: new foo" << std::endl; 
    foo *f = new foo(); 
    } catch (const char *e) { 
    std::cout << "heap exception: " << e << std::endl; 
    } 

    try { 
    std::cout << "stack: foo" << std::endl; 
    foo f; 
    } catch (const char *e) { 
    std::cout << "stack exception: " << e << std::endl; 
    } 

    return 0; 
} 

あなたは、コンストラクタから例外をスローしているが、あなたはそれがあまり有用ではありませんこれらの状況は、このうように、コンストラクタで例外をスローするconstructor.Inのメモリ(ヒープ)を割り当てるような状況があるitself.Butクラスが初期化に失敗した場合、既に例外がスローされているので、クラスのために呼び出されたデストラクタはありません(デストラクタでは、割り当てられたメモリは空きで解放されます)。シナリオまたはユースケースです。すべての状況でコンストラクターに例外がスローされることはありません。

関連する問題