tags:

views:

95

answers:

4

In code:

struct Rep
    {
        const char* my_data_;
        Rep* my_left_;
        Rep* my_right_;
        Rep(const char*);
    };

typedef Rep& list;

ostream& operator<<(ostream& out, const list& a_list)
    {
        int count = 0;
        list tmp = a_list;//----->HERE I'M CREATING A LOCAL COPY
        for (;tmp.my_right_;tmp = *tmp.my_right_)
        {
            out << "Object no: " << ++count << " has name: " << tmp.my_data_;
            //tmp = *tmp.my_right_;
        }
        return out;//------>HERE a_list is changed
    }

I've thought that if I'll create local copy to a_list object I'll be operating on completely separate object. Why isn't so?

Thanks.

+1  A: 

I assume list is meant to be the same as Rep.

You are only copying the the pointer to the first node in the list. You are not copying the data, nor the rest of the nodes of the list. You are doing a shallow copy of the first node of the list. If you would also copy the objects themselves it would be deep copy.

Anders Abel
So does it mean that I would have to provide cpy ctor for Rep in order to make this code work correctly?
There is nothing we can do
Yes, you will have to do that, one that traverses the list and makes a copy of each node and each node's data.
Anders Abel
He is not making a copy of the pointer. He is making deep copies of the Rep structs (into a local Rep struct), but a shallow copy of the list of which the Reps are elements. But he is not changing the copy (except to copy next elements into it) or the objects to which the pointers in the Rep struct point, so I don't see where the changes he is referring to could happen. Also, his for loop will miss the last element in his list, so he will have to restructure it.
Tim Schaeffer
+4  A: 

You've typedef'd list to be a Rep &. That means tmp isn't a copy. It's just another reference. Anything you do to tmp will be done to a_list.

Kristo
You are absolutely right.
There is nothing we can do
+3  A: 

const list& a_list - compiler error, reference to reference is illegal.

tmp = *tmp.my_right_ is very bad. Use pointers instead of reference. The thing is that tmp is reference to a_list. a_list is changed when you write tmp = *tmp.my_right_.

Alexey Malistov
A: 

I'm assuming you're rolling your own list as an educational exercise. When you do this for real, know that the standard library provides all this functionality for you.

std::list<std::string> myData;

// One way to print everything in the list.
int count = 0;
for (std::list<std::string>::iterator i = myData.begin(); i != myData.end(); ++i)
{
    std::cout << "Object no: " << ++count << " has name: " << *i;
}
Kristo
Thanks, yes I'm doing this as an exercise.
There is nothing we can do