5

我仍在探索 C++,试图弄清楚它是如何工作的,并遇到了令我困惑的事情。

我有一个只包含 alist<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一个带有一个参数的成员函数来使其工作,所以我假设从构造函数传递列表由于某种原因不起作用,或者非成员函数不能更改成员变量,但这些似乎是我的编译器很容易掌握的东西。(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) 

thenlstring是按值传递的,这意味着您没有使用在函数调用中传递的同一个对象。您只需制作此对象的副本,即使您在函数体中修改它,您也只修改此副本。

如果你想修改你传递的对象,你应该通过引用传递它,你可以通过使用来实现&

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