mardi 29 novembre 2016

How do const references as return values work in C++

I am learning C++ again after a while and have a problem understanding const references as return values. So here is what I've got: a class, Foo, which holds a std::list as member:

class Foo
{
    std::list<int> mList;
    Foo() { mList.insert(mList.end(), { 1, 2, 3 }); }
    size_t size() const { return mList.size(); }
};

Creating a foo object from class Foo and calling foo.size() returns 3, which is fine. Now I want to retrieve this list mList, with two requirements:

  • I don't want to allow the caller to modify the original list; and
  • I don't want to create a copy of each list member when retrieving the list.

So after reading a bit on this topic I decided to return a const reference to the list. Thus I added the following method to Foo:

const std::list<int>& getList() const { return mList; }

What I expected was that this would return a reference to the list mList, so that I can access the original data within this list. But since it's a const reference, I also expected that I would not be able to modify the returned list/reference.

However, playing with this a bit I found out the following:

Foo foo;
cout << foo.size() << endl;  // returns 3
std::list<int> l = foo.getList();
l.clear();
cout << foo.size() << endl;  // returns 3 again

Now this surprises me and leeds me to two questions:

  1. Since the 2nd cout returns 3 again, the call to clear() obviously does not modify the original foo.mList object. But why is that the case if I returned a reference? Is there a copy happening during the return?
  2. Why am I allowed to call l.clear() in the first place, if I have received a const (!) reference?

Aucun commentaire:

Enregistrer un commentaire