0

私は Glib::ustring メンバーを持つクラスを持っています (あなたがそれに慣れていない場合は、それが std::string であると想定してください)。これには長い文字列、つまり少なくとも 1 つの段落、おそらくさらにいくつかの段落が含まれることが期待されます。たぶん10段落以上。文字列は GUI に表示される予定なので、将来的にはテキスト ウィジェットのバッファに格納される可能性がありますが、今のところは、私の C++ クラスの単なる文字列メンバー オブジェクトです。

問題は、文字列をコンストラクターに渡す方法と、それを set_string() セッター メソッドに渡す方法です。長い文字列は大きなコピーを意味するため、適切な解決策は右辺値参照を取得し、引数をメンバー オブジェクトに std::move することです。しかし、私はまた、クラスインターフェイスが驚くほど使いにくく、理解しにくいものにしたくありません。ご存知のように、最小の驚きのルールです。

だから私は考えていました、この場合に期待される/一般的な解決策は何ですか?

(setter メソッドの場合は、別のオプションがあります。編集は GUI で行われるため、GUI に文字列を直接編集させるだけで、setter メソッドを使用する唯一の方法は、文字列をプログラムで完全に置き換えることです。たとえば、リセットするか、最近の編集を元に戻すなどです。 )

class MyClass
{
public:
     explicit MyClass (Glib::ustring str);
     void set_string (Glib::ustring str);
private:
     Glib::ustring str;
}

(gtkmm などの既存のライブラリのコードを const 参照で文字列を取得しているのを見たことがありますが、最適化を許可するために値渡しという回答を含む SO の投稿も見ました)

4

2 に答える 2

4

http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

あなたの関数は、効率的な移動コンストラクターを持っているstringと仮定して、値を取る必要があります。string

文字列が長くなると予想される場合、呼び出し元はstd::move値を呼び出してセッター/コンストラクターに渡します。std::moveデータを移動していることがかなり明確になるため、これは驚くべきことではありません。

システムの並行性が適度な量に過ぎず、文字列をほとんど変更しない場合 (実際、ほとんどの文字列は変更されるよりもはるかに多く共有されます)、不変文字列への共有ポインターは実際には非常に便利なパターンです。(共有書き込みデータは参照カウントであるため、高レベルの同時実行では競合が発生する可能性があります)

于 2013-02-12T16:06:55.430 に答える
1

私は参照に行きます(それらを渡すだけでなく、参照を保存することもできます)。ただし、セッターは参照を再配置する必要があり、これは不可能です。構築後に文字列を本当に変更する必要がある場合は、ポインター (おそらくスマート ポインター) を使用する必要があります。

周囲のコードによっては、文字列の共有所有権を使用したい場合があります。この場合、私はstd::shared_pointer<GLib::ustring>. セッターが必要な場合。(それ以外の場合は、リファレンスの方が適切です。)

「いくつかの段落」はそれほど長い文字列ではないことに注意してください。ユーザー インターフェイスでは、数ミリ秒の遅延 (たとえば、テキスト ファイルの読み込み時など) は完全に許容されます。いつものように、まずコードをプロファイリングし、ボトルネックを検出してから、高速化が必要な場合は最適化してください。

于 2013-02-12T16:02:16.717 に答える