2012-03-14 7 views
4

私はboost :: bindが行う関数オブジェクトの内部コピーの種類を理解したいと考えていました。これらのオブジェクトのコンストラクタは呼び出されないように見えるので、これは一種の「非常に浅いコピー」と推測されていましたので、動的メモリ割り当てを導入していくつかのエラーを生成しました。しかし、以下のコードの実行時出力は、3つのデストラクタがバインドによって作成された内部コピーを追加で呼び出すように見えます。boost :: bind内部コピー/コピー?

using namespace std; 
using namespace boost; 

class M{ 
    int *somedata; 
public: 
    M(){ somedata=new int[5]; cout<<"from cstr\n"; somedata[1]=0;} 
    ~M(){cout<<"from dstr\n"; delete somedata;} 

    int operator()(int i){ cout<<++somedata[i]<<endl; return 0;} 
}; 


int main() 
{ 
    M instM; 

    bind<int>(instM,1)(); 
    //bind<int>(&M::operator(),&instM,1)(); //this works with no errors, of course 

    instM(1); //would not change the order of output 

    return 0; 
} 

出力にはいくつかの追加のパズルが表示されます。最初のdstrイベントがoperator()の呼び出しの前に来るのはなぜですか?最後に失敗したデストラクタコールの前に "2"にも注意してください。

from cstr 
from dstr 
1 
from dstr 
bind_copy(73365) malloc: *** error for object 0x1001b0: double free 
*** set a breakpoint in malloc_error_break to debug 
from dstr 
bind_copy(73365) malloc: *** error for object 0x1001b0: double free 
*** set a breakpoint in malloc_error_break to debug 
2 
from dstr 
bind_copy(73365) malloc: *** error for object 0x1001b0: double free 
*** set a breakpoint in malloc_error_break to debug 

だから問題は誰でも簡単に説明できますか、どのような種類のコピーが作成できますか?

...バインドが単に(ここではデフォルトの)コピーコンストラクタを使用していると思った後、このcstrのいくつかのカスタム版を提供した後(メモリ割り当てとコピーの要望に応じて)、出力はきれいになりますが、パズルは残ります。3つのの呼び出しコピーコンストラクタ。 この場合、boost :: bindは、関数オブジェクトののコピーをにします。なぜ、どの順番で?(入れ子にされたboost :: bindsの場合、内部コピーの数が非常に爆発的に増加する可能性があります)

cp-cstrが定義され、いくつかの "遺産マーカー"が追加された出力CSTR)は "-C" を追加します。

from cstr P 
from cp cstr P-C 
from cp cstr P-C-C 
from cp cstr P-C-C-C 
from dstr P-C-C 
P-C-C-C:1 
from dstr P-C-C-C 
from dstr P-C 
P:1 
from dstr P 
+0

'--std = C++ 0x'、' namespace'を 'std'と' boost'の両方でコンパイルし、 'bind'という名前の関数をコンパイルするとどうなるのでしょうか... – Benoit

+0

@ Benoit:付与されました。しかし、これは上記のエラーには何ら影響しません。 –

+0

私はこれに対する答えも知りたいです。私のOSでの新規作成と削除は非常に高価で、メンバー関数のバインド時にシステムが遅くなるのが分かります。メンバー関数がコピーされているかどうかについてのドキュメントはありません。 – Ant

答えて

2

here参照:デフォルトでは

を、バインドが提供する関数オブジェクトのコピーを作成します。 boost :: refとboost :: crefは、コピーではなく関数オブジェクトへの参照を格納するために使用できます。これは、関数オブジェクトがコピー不可能で、コピーにコストがかかる、または状態を含む場合に便利です。もちろん、この場合、プログラマーは関数オブジェクトがまだ使用されている間は破壊されないことを保証することが期待されます。

+0

thxだが、私はQを投稿する前に医者のことを読んだ(そうでなければ、StOvの不公平な使用になる)。それにもかかわらず、ドキュメントは何が起こるかについてあまりにも明白ではありませんでした。私はカスタム定義されたcp cstrの効果を使って質問を編集しました。 boost :: bindはこの単純なケースで_three_内部コピーを作成することを示しています。このプロセスがどのように進行するかについての情報は高く評価されます。 –

関連する問題