web-dev-qa-db-ja.com

コンストラクターへの参照渡し

メンバーへの参照を割り当てるとメンバーが参照になるかどうかを確認することにしました。それをテストするために次のスニペットを書きました。メンバー変数として_std::string_を持つ単純なクラスWrapperがあります。コンストラクターで_const string&_を受け取り、それをパブリックメンバー変数に割り当てます。後でmain()メソッドでメンバー変数を変更しますが、コンストラクターに渡したstringは変更されません。どうしてですか? Javaで変数が変更されたと思いますが、なぜこのコードスニペットでは変更しないのでしょうか?この場合、参照はどのように正確に機能しますか?

_#include <iostream>
#include <string>
using namespace std;

class Wrapper
{
public:
   string str;

   Wrapper(const string& newStr)
   {
      str = newStr;
   }
};

int main (int argc, char * const argv[]) 
{
   string str = "hello";
   cout << str << endl;
   Wrapper wrapper(str);
   wrapper.str[0] = 'j'; // should change 'hello' to 'jello'
   cout << str << endl;
}
_
29
rcplusplus

本文の変数はstd::stringです。

パラメータ変数はconst std::string&です。

参照のconstは常に「低レベルのconst」です。つまり、実際のオブジェクトではなくオブジェクトのタイプを変更します。

対照的に、「トップレベルのconst」は実際のオブジェクトを変更します。明確にするために 最上位の定数のC++入門 を読んでください。

引数を渡したときの割り当ては次のようになります。

const std::string& = std::str; //Values are ommited
// i.e const std::string newStr = std::string str

const type referenceを許容できるnon-const valueで初期化しています。その参照を使用してstd::string strの値を変更することは想定されていません。また、コンストラクター内でnewStrの値を変更しようとすると、でコンパイルエラーが発生します。

次に、コンストラクタ内で別の割り当てを行っていますが、これも許容されます。

std::string = const std::string 

wrap.str[0]strmainを変更しなかったという事実は、class strをインスタンス化するために参照が使用されたにもかかわらず、class strは独自のオブジェクトを持ち、main strにリンクされていないということです。 。パラメータでその参照を使用すると、そのパラメータがmain strにリンクされるだけです。 main strclass strではありません。

クラス変数が参照されていれば、変更されている可能性があります。

1
Jesus Christ