func(文字列)の代わりにfunc(文字列&)として文字列を渡すことの利点はありますか?これは、文字列を関数の引数として渡すメモリ効率のよい方法です。
答えて
あなたは値によって参照を渡すのではなく、あなたが関数呼び出しでコピーを作成する必要があることを意味した値によってオブジェクトを渡していることを、よく、参照によってオブジェクトを渡します。関数は、渡されたオブジェクトを変更したりしません
- :
しかし、パッシング・バイ・参照することはあなたが知っておく必要があります質問の新しいセットを導入して?そうでない場合は、
const
修飾子を入れてください - 関数はオブジェクトを変更する必要がありますが、変更を関数境界外に公開する必要はありませんか?その場合、本当に欲しいのはコピーです。
- この関数は、渡されたオブジェクトの参照をどこかに保存しますか?その場合、オブジェクトの所有権がどのように渡され、削除するのが安全なのかを理解する必要があります。パッシング・バイ・参照すると、関数呼び出し安く作るという理由だけであなたはどのような場合には、それを使用しなければならないことを意味しません:あなたは、これらの問題
点であるに対処するsmart pointersを使用することができます。
一般的に、パフォーマンスに関する限り、参照渡しは値渡しよりも優れています(組み込みデータ型は除外します)。だからはいfunc(string&)
はfunc(string)
より優れています。関数が終了すると、渡されたを変更することができます。 string
を変更しない場合は、func(const string&)
を使用してください。
さらに、STLではstring
が最適化されていることを覚えています。値によってstring
を渡すと、必ずしもヒープに新しい文字列が作成されるとは限りません。値渡しは、あなたが期待するほど高価ではないかもしれません。例えば
string s1 = "hello"; // new buffer allocated on heap and copied "hello"
string s2 = s1; // s2 and s1 both 'may' refer to same heap
...
s1 += " world"; // s2 continue referring to old heap ...
// new heap created to accomodate "hello world" referred by s1
'string'最適化の問題について少し詳しく説明します:' strings'は[COW](http://en.wikipedia.org/wiki/Copy-on-write) 'dです。 'string'を値で渡すと、新しい' string'が作成されますが、元の 'string'と新しい' string'の間で基礎となるデータ(例えば文字配列)が共有されます。したがって、ローカルコピーが変更されない限り、オーバーヘッドはありますが、それほど多くはありません。 **編集:**私は私のコメントを書いている間にこれを説明するために編集したように見えます。 – Mac
@Macこれは必ずしも真実ではなく、実装によってはCOWがあり、そうでないものもあれば、C++ 11のいくつかの変更がCOW文字列で準拠した標準ライブラリを提供することを不可能にしたと私は考えています。この最後の部分がわからない。 –
@DavidRodríguez-dribeas:絶対に正しい - 私が言っていることは 'string'sは*典型的な* COWだと言った。 – Mac
func(string &)
は参照によって文字列を渡します。これは、コピーされず、関数がそれを変更できることを意味します。
func(string)
は値で文字列を渡します。つまり、コピーが作成され、その関数はその文字列のローカルコピーのみを変更できます。
コピーせずに文字列を渡しますが、変更されないようにするには、func(const string&)
を使用してください。
あなたの関数が引数のコピーをとる必要がある場合は、値渡しが望ましいです。参照を渡す
さらに、 'func'がそのパラメータを変更する必要がない場合は' func(const string&) 'を考慮する必要があります。とにかく 'func(string)'を持っていると考えると、関数はこのパラメータを変更できないので、 'func(const string&)'を使う必要があります。... – MichalR
「関数が引数のコピーをとる必要がある場合、値渡しが望ましい。どのように役立つだろうか? –
@Paul:それは引数とスクリプトのために別々の変数を必要としないので、関数をやや簡単にし、エラーを起こしにくくなります。 –
は、通常、複雑な型のため、より効率的になりますが、あなたは関数がそれを変更できるようにしたい場合を除き、それはconst
への参照する必要があります:
void f(string); // function gets its own copy - copying may be expensive
void f(string&); // function can modify the caller's string
void f(string const&); // function can read the caller's string, but not modify it
ます。またfunc(const string&)
の代わりに使用することができますfunc(string&)
を使用して、渡された参照パラメータが関数内で誤って変更されていないことを確認します。
はい。参照を渡すことは常に効率的です。
文字列は値によって格納され、コピーにはO(n)の長さがかかることがあります(コピーには文字列の長さに比例した時間がかかります)。また、通常はコピーよりもはるかに高価なヒープメモリが割り当てられます。
unintenionalな変更を避けるために、reference-to-const、つまりfunc(const string &)を渡すことも考えられます。
string
として渡すと、文字列が最初にコピーされ、コピーが関数に送信されます。文字列などの高価なオブジェクトを渡す最善の方法は、関数で修正する必要がない場合はconst string&
です。
const
が重要です。まず、関数内で文字列が変更されないようにします。また、func("this is a litearal because it isn't inside a variable")
を使用せずにリテラルを関数に渡すことはできません。
また、移動セマンティクスを使用してrvalue参照最適化を使用することもできます。
void func(string &&s)
{
myS = std::move(s);
}
- 1. 関数の引数として文字列値を渡す
- 2. NULL文字列を引数として渡すこと
- 3. 座標を関数の引数として渡す方法は?
- 4. Cで関数の引数としてENUMを渡す方法
- 5. 適切に可変引数テンプレート関数内のラムダにCの文字列を渡す方法ここで
- 6. anglejs ng-click関数に文字列引数を渡します
- 7. 多数の文字列をマップに格納する最もメモリ効率の良い方法は何ですか?
- 8. 関数に文字列引数を渡す - それはなぜ機能していないのですか?
- 9. 文字列引数をPHP関数のJS関数に渡すには?
- 10. 関数を書くときに文字列/文字引数を渡すR
- 11. C++のクラスコンストラクタの引数として関数を渡す方法
- 12. 文字列を関数の引数として渡せませんJquery
- 13. str.format()関数に複数の文字列を渡す方法
- 14. 文字列を引数として渡すには?
- 15. Matlab bashの引数としてパス文字列を渡す
- 16. C++引数としてCスタイルの文字列を渡す
- 17. SICStus Prolog関数に文字列を変数として入れて文字列として返す方法は?
- 18. PHP:文字列を関数の引数に入れる正しい方法
- 19. 引数としての関数の効率的な使用
- 20. 引数としてsize_tを渡す「効率」
- 21. angular2:Typescript関数で文字列をパイプに渡す方法は?
- 22. QTとC++を使用して関数に文字列引数を渡す方法
- 23. のonclick関数内で文字列パラメータを渡す方法
- 24. printf文字(%c、%d)を関数の引数として渡す方法はありますか?
- 25. 複数行のHTMLを文字列引数としてHTMLヘルパーに渡すことはできますか?
- 26. C:なぜ文字列リテラルを関数の引数として渡せないのですか?
- 27. luaのdissactorでProtofield.string()関数の引数としてテーブルデータを渡す方法は?
- 28. WordPress - add_filter関数と文字列引数?
- 29. 関数の入力として文字列のリストを渡す
- 30. C#で高速かつメモリ効率の良い方法で多数の頂点と色を渡す方法
ケース2では、私はまだパラメータとして 'const&'を置いて、関数の内部にコピーを作成します。特に、コピーを行う前に関数が失敗/復帰する可能性を考慮してください。 – xanatos
@xanatosはい、可能ですが、この関数が頻繁に呼び出され、コピーを実行する前に戻る可能性が高い場合、引数を値渡しする方が簡単です。 – akappa
(私はBjörnPollexの答えにSteve Jessopの議論がこの論争の中で良いと思っています) – akappa