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. Cで関数の引数としてENUMを渡す方法
- 2. 関数に文字列引数を渡す - それはなぜ機能していないのですか?
- 3. str.format()関数に複数の文字列を渡す方法
- 4. C++引数としてCスタイルの文字列を渡す
- 5. QTとC++を使用して関数に文字列引数を渡す方法
- 6. のonclick関数内で文字列パラメータを渡す方法
- 7. 引数としてsize_tを渡す「効率」
- 8. 複数行のHTMLを文字列引数としてHTMLヘルパーに渡すことはできますか?
- 9. rの関数内で関数に引数を渡す方法
- 10. バッチスクリプト内の関数に引数(コマンドライン引数ではない)を渡す方法
- 11. 関数名を文字列として渡すことで任意の関数を動的に呼び出す
- 12. CreateProcess関数に文字列を渡す方法は?
- 13. soap lite渡し文字列引数
- 14. メモリ効率のよいC++文字列(インターン、ロープ、コピーオンライトなど)
- 15. 引数を渡すことによる関数のトラップ?
- 16. Perlで関数を引数として別の関数に渡して呼び出す方法は?
- 17. 関数のパラメータとして文字列の配列を渡すには?
- 18. Powershellの関数に文字列や文字列を渡す
- 19. javascript:文字列内のonclick関数への引数としてオブジェクトを渡します。
- 20. 複数の引数を含む文字列を渡す
- 21. 複数の文字列を1つの関数パラメータとして渡す
- 22. 関数名を引数として渡すことはできますか?
- 23. 文字列と関数内の変数を別の関数に渡す
- 24. C++で関数を引数として渡すときのエラー
- 25. ブール関数に文字列を渡す
- 26. char型変数を型文字列関数に渡す関数
- 27. 非静的引数を持つ関数を別の関数にjavascriptの変数として渡すにはどうすればよいですか?ここ
- 28. clojure関数を文字列として返す方法
- 29. メモリ効率が良い、SQLiteデータベースかXML文字列[]ですか?
- 30. アンカータグで複数のクエリ文字列を渡す方法は?
ケース2では、私はまだパラメータとして 'const&'を置いて、関数の内部にコピーを作成します。特に、コピーを行う前に関数が失敗/復帰する可能性を考慮してください。 – xanatos
@xanatosはい、可能ですが、この関数が頻繁に呼び出され、コピーを実行する前に戻る可能性が高い場合、引数を値渡しする方が簡単です。 – akappa
(私はBjörnPollexの答えにSteve Jessopの議論がこの論争の中で良いと思っています) – akappa