5

私はまだC++を調べて、それがどのように機能するかを理解しようとしていて、私を困惑させる何かに出くわしました。

を保持するだけのクラスがlist<string>あり、いくつかのメンバー関数があります

class String_list {
      public:
            String_list(istream&);
            //other functions
            list<string> listing;
};

非メンバー関数を使用するようにコンストラクターを作成しました

String_list::String_list(istream& in) { get_strings(in, listing); }

istream& get_strings(istream& in, list<string> lstring)
{
  if(in) {
       lstring.clear();

       string word;

       while (in >> word) 
               lstring.push_back(word);

       in.clear();
       }
  return in;
 }

問題は、get_string関数は機能しているように見えますが、listing渡したメンバー変数が変更されないことです。

に変更するだけget_stringsで1つの引数を持つメンバー関数を作成することで機能させることができるので、コンストラクターからのリストの受け渡しが何らかの理由で機能しないか、非メンバー関数が機能しないと思いますメンバー変数を変更しますが、これらは私のコンパイラーが簡単に理解できるようなもののようです。(istream& in)lstringlisting

.size()メンバーリストが常に0である実行可能ファイルを実行したときだけ、コンパイラはコードに問題を認識しません。

4

3 に答える 3

10

あなたは参照によって渡す必要がありlstringます:

istream& get_strings(istream& in, list<string>& lstring)

コードはコンパイルされ、記述されたとおりに機能します。つまり、lstringの値を渡して、それをコピーします。すべての変更は一時オブジェクトに対して行われ、オブジェクトが破棄されると破棄されます。

于 2013-01-29T16:29:36.583 に答える
9

メンバー変数のコピーを関数に渡します。ローカルコピーは変更されますが、メンバー変数は変更されません。

関数のシグネチャを変更しget_stringsて、リストオブジェクトへの参照を取得すると、次のように機能します。

istream& get_strings(istream& in, list<string>& lstring)
{
   // ...
}

これはカプセル化を破りますが、あなたの場合(メンバー変数をその関数に直接公開します)。より良い方法は、get_strings関数が設定したリストのコピーを返し、それを初期化子リストのクラスのメンバーに割り当てることです。このような:

list<string> get_strings(istream& in)
{
   list<string> r;
   // ...
   return r;
}

次に、コンストラクター:

StringList::StringList(istream& in) : listing(get_strings(in))
{
   // ...
}
于 2013-01-29T16:29:18.487 に答える
4

C ++では、明示的に行わない限り、参照ではなく値で渡します。したがって、関数を宣言すると、次のようになります。

istream& get_strings(istream& in, list<string> lstring) 

次にlstring、値によって渡されます。これは、関数呼び出しで渡したのと同じオブジェクトを使用していないことを意味します。このオブジェクトのコピーを作成するだけで、関数本体で変更しても、このコピーのみを変更します。

渡すオブジェクトを変更する場合は、参照によって渡す必要があります。これは、次を使用して実現できます&

istream& get_strings(istream& in, list<string>& lstring) 
于 2013-01-29T16:36:15.413 に答える