3

私はC++を初めて使用します。std::stringバッファを解放するタイミングを決定するために参照カウントを使用すると想定していました。次の例では、sバッファはf()戻り時に解放されます。give_ownership_of文字列バッファの所有権を解放したくない場合はどうすればよいですか?

void f() 
{ 
    string s = read_str();  
    give_ownership_of(s); 
}

アップデート

質問にさらに詳細を追加させてください。実際のコードは次のようになります。

string read_str();

void write_str_async(const char *str, void (*free_fn)(const char*));

void f() {
  string s = read_str();
  // write_str_async() need to access the buffer of s after f() returns.
  // So I'm responsible to keep s alive until write_str_async() calls free_fn to release the buffer when the write is done.
  // The PROBLEM here is that s will be released when the variable scope ends. NOTE: I'm not able to change either read_str() or write_str_async() here.
  write_str_async(s.c_str(), my_free_fn);
}
4

3 に答える 3

4

C ++ 11では、ムーブと呼ばれるこのようなものを追加しました。std::stringムーブコンストラクタとムーブ代入演算子があります。

ここでのコンパイラsは、それが存続期間の終わりに達したことを判断できるため、コンパイラにコピーするgive_ownership_ofのではなく、移動できます。これは、基本的に、の内容ではなく、いくつかの整数/ポインタをコピーするだけstd::stringです。これは参照による受け渡しよりもまだ遅いことに注意してください。したがって、参照が機能する場合は、それを優先する必要があります。

https://akrzemi1.wordpress.com/2011/08/11/move-constructor/

std::shared_ptr実際の所有権の共有はないため、これを使用しないことを強くお勧めします。

移動を明示的にしたい場合は、次のようにします。

give_ownership_of(std::move(s));

std::move関数から値を返すときに使用する必要はありません(実際には使用しないでください) 。通常どおり値を返します。多くの場合、コンパイラーは「戻り値の最適化」を実行できます。これは、コピーや移動がないことを意味します。これは、参照によって値を渡し、それに割り当てるのと似ていますが、実際にはオプティマイザにもう少し余裕を持たせる点が異なります(これstd::stringは、が何もエイリアスしない一意のオブジェクトであることがわかっているためです)。また、読むのも簡単です。

于 2013-01-03T02:19:37.087 に答える
1

の基になるデータの所有権を取得する標準的な方法はありませんstd::string。一般に、代わりに文字列オブジェクト自体を返すか、呼び出し元に参照を渡す必要があります。

void f(std::string& s) {
    s = read_str();
}
于 2013-01-03T01:54:13.650 に答える
0

質問はあいまいですが、以下の例はすべての選択肢を示しているはずです。最後のものはおそらくあなたが望むものであり、それはC ++ 11(std::moveおよび右辺値参照)で追加された新機能です。

std::stringこれにより、同じタイプの新しいオブジェクトにバッファを転送できますが、完全に削除することはできません。これを無視してstring、バッファメモリをバイトとして扱うことはできますが、割り当て解除は、を破棄して実行する必要がありますstring

// will retain s for duration of function
void give_ownership_of( std::string &s );

// will retain a copy of s for duration of function
void give_ownership_of( std::string s );

struct give_ownership_of {
     std::string s;

     // will retain a copy of in_s for object lifetime
     give_ownership_of( std::string const &in_s ) : s( in_s ) {}

     // will transfer buffer of in_s to s and retain that (C++11 only)
     // you would write give_ownership_of( std::move( s ) );
     give_ownership_of( std::string &&in_s ) : s( std::move( in_s ) ) {}
};
于 2013-01-03T02:22:25.803 に答える