为什么成员变量没有传递给修改过的函数?

App*_*ple 5 c++ class

我仍然在探索C++,试图找出它是如何工作的,并遇到了令我困惑的事情.

我有一个简单地拥有一个list<string>并且具有一些成员函数的类

class String_list {
      public:
            String_list(istream&);
            //other functions
            list<string> listing;
};
Run Code Online (Sandbox Code Playgroud)

我编写了我的构造函数来使用非成员函数

String_list::String_list(istream& in) { get_strings(in, listing); }
Run Code Online (Sandbox Code Playgroud)

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;
 }
Run Code Online (Sandbox Code Playgroud)

问题是,虽然get_string函数似乎有效,但它不会更改listing我传递给它的成员变量.

我可以通过只更改为get_strings使用一个参数创建一个成员函数来使它工作,所以我假设从构造函数中传递列表由于某种原因不起作用,或者非成员函数不能改变成员变量,但这些似乎是我的编译器很容易接受的东西.(istream& in)lstringlisting

当我运行成员列表总是.size()为0 的可执行文件时,我的编译器看不到代码的任何问题.

Bar*_*icz 10

你应该通过lstring参考传递:

istream& get_strings(istream& in, list<string>& lstring)
Run Code Online (Sandbox Code Playgroud)

代码在编写时编译并工作:传递lstring 的,从而复制它.所有更改都在临时对象上进行,然后在销毁对象时丢弃.


Cha*_*had 9

您正在将成员变量的副本传递给该函数.修改本地副本,而不修改成员变量.

更改get_strings函数的签名以获取对列表对象的引用,这将起作用:

istream& get_strings(istream& in, list<string>& lstring)
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

虽然这打破了封装,但在你的情况下(直接将成员变量暴露给该函数).一个更好的方法可能是让get_strings函数返回它填充的列表的副本,然后将它分配给初始化列表中的类成员.像这样:

list<string> get_strings(istream& in)
{
   list<string> r;
   // ...
   return r;
}
Run Code Online (Sandbox Code Playgroud)

然后你的构造函数:

StringList::StringList(istream& in) : listing(get_strings(in))
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)