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

时间:2013-01-29 16:27:54

标签: c++ class

我仍然在探索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更改为(istream& in),即可将lstring成为listing的成员函数,因此我可以通过构造函数中的列表由于某种原因不起作用,或者非成员函数不能更改成员变量,但这些似乎是我的编译器很容易接受的东西。

我的编译器没有看到代码的任何问题,就在我运行成员列表的.size()为0的可执行文件时。

3 个答案:

答案 0 :(得分:10)

您应该通过引用传递lstring

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

代码编写并按原样编写:传递lstring的,从而复制它。所有更改都在临时对象上进行,然后在对象被销毁时丢弃。

答案 1 :(得分: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))
{
   // ...
}

答案 2 :(得分:4)

在C ++中,除非您明确地执行,否则您将通过值传递,而不是通过引用传递。所以如果你声明你的功能:

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

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

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

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