63352


こんにちは、C++の初学者です。  
ビャーネ・ストラウストラップ先生の『プログラミング言語C++
第4版』から以下のexampleを引用しました。compose1は引数に&をつけて、compose2にはつけていません。どちらも同じ出力をするのですが、これらの違いは何でしょうか。ご教授願います。

[code]

    #include <string>
    #include <iostream>
    using namespace std;
    
    // what's the difference between compose1 and compose2?
    string compose1(const string& name, const string& domain) {
            return name + '@' + domain;
    }
    
    string compose2(const string name, const string domain) {
            return name + '@' + domain;
    }
    
    int main() {
    
            string f = "dmr";
            string g = "bell-labs.com";
            auto addr1 = compose1(f,g);
            cout << addr1 << ':' << f << ',' << g << endl;
    
            string h = "dmr";
            string i = "bell-labs.com";
            auto addr2 = compose2(h,i);
            cout << addr1 << ':' << h << ',' << i << endl; // Outputs were same...
    }
    
[/code]


CC BY-SA 4.0
2020-02-25T15:08:23.060
63349
2020-02-26T03:02:10.847
2020-02-26T00:00:34.567
3475
37961
question
c++ c++11
引数での const string& と const string の違い


以下の記事が良く解説されています。  
[C++ 値渡し、ポインタ渡し、参照渡しを使い分けよう](https://qiita.com/agate-
pris/items/05948b7d33f3e88b8967)

> C++ では, 関数呼び出しの際, 引数の渡し方が大きく分けて 3 種類ある. それぞれ「値渡し」「ポインタ渡し」「参照渡し」だ.
>
> **値渡しの基本**  
>  値渡しは主に int , float , bool , char 等の組み込み型を使う際によく用いる. 値渡しを行うと,
> 平たく言えばコピーが行われる1. int が引数であれば, その数値がコピーされるので,
> コピーされた引数を変更しても関数を呼び出した側の変数は書き換えられない.
>
> **ポインタ渡しの基本**  
>  ポインタ渡しは変数のメモリ上のアドレスを渡す記法である. 値渡しとは異なり, 渡されたアドレスを間接参照する事で,
> 関数の呼び出し元の変数を書き換える事が出来る.
>
> **参照渡しの基本**  
>  参照渡しは C には無く, C++ で新たに追加された記法である. その実態は殆どの場合, より安全で,
> 制約の厳しいポインタであると言って差し支えない.

**compose1()は参照渡し、compose2()は値渡しです。**

今はどちらの関数も渡されたパラメータを連結して新しい文字列を作っているだけなので、渡され方が違っても結果に変わりはありません。またどちらも`const`ということで変更も行わないことになっているので尚更変わる要素がありません。

これがもしパラメータが`const`ではなく、さらに渡された文字列自身を書き換える処理があった場合には、影響範囲が変わります。

compose1()でパラメータ文字列を書き換えると、main()で初期化した変数が書き換わります。  
compose2()でパラメータ文字列を書き換えても、その変化はcompose2()の中で閉じていて、main()の変数には影響がありません。

* * *

タイトルが編集されて`const`にも注目される感じなので追記：

ちょっとゴチャゴチャしていますが、この辺の記事を参照。  
少しだけ引用しておきますので、詳細や全体はリンク先を見てください。

[C++の基礎 : const
修飾子](http://www.s-cradle.com/developer/sophiaframework/tutorial/Cpp/const.html)

> const 引数  
>  関数の引数に const を指定すると、その関数の中では値を書き換えることができなくなります。これはクラスのメンバ関数であっても同じです。
>
> const
> 引数は参照引数と共に使われることが多いです。参照引数は実際にはポインタであるため、大きな構造体やクラスを引数に渡すときにも効率のよい方法ですが、const
> をつけない参照渡しであれば、関数により中身を書き換えられる可能性があることになります。参照渡しに const
> 修飾子をつけることにより、引数の中身を書き換えないことを宣言することができます。

[const を使いこなそう](https://kumikomiya.com/act-professionally-with-const/)

>   2. 参照を修飾する  
>  参照は C++ で登場した概念です。その使用場面はほぼすべて、クラスのインスタンスを引数にするときであるといって差し支えありません。
>

[値渡しにconstを付ける？付けない？](http://hakutoitoi.hatenablog.com/entry/20081023/1224777312)

> そもそもconstを付ける意味って？  
>  オブジェクトの場合  
>  無駄なコピーをしないために参照渡しをする。  
>  そのときに渡した値に変更を加える関数かどうかでconstを付けるか付けないかが決まる。
>
> 組み込み系の場合  
>  intなどの組み込み系は  
>  [Effective C++ 原著第3版 (ADDISON-WESLEY PROFESSIONAL COMPUTING
> SERIES)](http://d.hatena.ne.jp/asin/4894714515/hakutoitoi-22)に書かれているように値渡しのほうが効率がいい。


CC BY-SA 4.0
2020-02-25T15:59:17.667
63352
2020-02-26T00:44:15.743
2020-02-26T00:44:15.743
26370
26370
63349
answer


compose1は参照渡しcompose2は値渡しですね。  
参照渡しの場合はデータの中身をコピーせず、そのアドレス（ポインター）を渡します。  
値渡しの場合は、データがコピーされます。  
string型の場合、文字数が多くなればなるほど値渡しではコピーに時間がかかって  
しまいますが、参照渡しの場合はコピーしないので、文字列の長さに関係なく、  
一定時間ですみます。  
また、参照渡しの場合、呼ばれた関数側で値を変更すると、それは元データを変更していることになりますが、値渡しの場合は元データは変わりません。


CC BY-SA 4.0
2020-02-26T03:02:10.847
63359
2020-02-26T03:02:10.847
24490
63349
answer