2016-07-14 11 views
2

私はファイル処理クラスを作成していますが、私が望む機能の1つは一時的にファイルの一部に移動してから検索する「エクスカーション」です。私はこれを自動的にしたいと思います。ちょうど保持エクスカーションオブジェクトを返しますC++の値とデストラクタ?

file.excursion(512); 

struct File { 
    ... 
    struct Excursion { 
     Excursion(File& file, off64_t new_off) 
      : pi_(make_shared<impl>(file, new_off)) {} 

    private: 
     struct impl { 
      impl(File& file, off64_t new_off) 
       : file(file), off(file.tell()) { 
       file.seek(new_off); 
      } 

      ~impl() { 
        file.seek(off); 
      } 

      File &file; 
      off64_t off; 
     }; 

     shared_ptr<impl> pi_; 
    }; 

    Excursion excursion(off64_t off) { 
     return Excursion(*this, off); 
    } 
}; 

はその後、私のようなもので遠足を開始することができます:アイデアは、私は私のファイルクラスで、次のようなコードを持っていると思いますですファイルへの参照と現在のオフセット。このオブジェクトが範囲外になると、ファイルオフセットが自動的に復元されます。これは、ファイルを解析して解析するコードでは非常に便利です。

私は(file.excursionからそのエクスカーションオブジェクトを返す場合は私の質問は、である)、そして何にそれを割り当てない、C++は完全に値をElideのデストラクタを呼び出すしないように許可されていますか?

編集:以下

パー、Zbynek Vyskovsky - kvr000が正しいか、デストラクタが省略されていません。 しかしのように、上記のようなエクスカーションを実行するとオブジェクトが返されます。オブジェクトはすぐに破棄され、何も割り当てられません。

hereを読むと、それはその関数評価から返される一時的な値なので、オブジェクトは作成された式を評価する最後のステップとして破棄されます。したがって、ではなく、は、囲みスコープの終わりまで持続します。したがって、この手法では、エクスカーションオブジェクトを上位スコープの変数に割り当てないと機能しません。

これは動作します:

Excursion ex = file.excursion(512); 

しかし、それは転がっダミー変数を持つように持つことは正しいことであるかどうかの意見の問題です。

+0

「類似」ルールを確認してください。 –

+0

あなたの使用方法を明確にすることはできますか? 'Excursion foo(){return file.excursion(512);}のようになります。 } '? – Barry

+1

いいえ、デストラクタは、リクエストした場合には省略できません。副作用があっても省略することができるのは、コピーだけです(もちろん、中間体の破壊ももちろんです)。 –

答えて

3

いいえ、デストラクタは無視できません。

コンパイラは最適化を実行し、コードの一部を削除することができます。これは、他のオブジェクトのグローバルな状態に影響を与えるデストラクタから別のメソッドを呼び出すと、ここでは明らかにそうではありません。

+0

本当に真です。オプティマイザが、建設+運賃のペア全体がノーオペレーションであることを理解するのに十分なほどスマートだった場合にのみ、それをすべて削除することができます。 – Angew

+0

実際、コピーエリッションでいくつかの副作用があるコードを最適化できます。 – stryku

+0

@stryku:コピーエリーションは、標準で特に指摘された特別なケースです。一般的なケースでは、副作用のあるコードを削除することはできません。 –

関連する問題