Hi I'm re-reading over a chapter of Alex Allains jumping into c++ and one stanza of the book goes against everything I've learned so far,heres what he basically says in the book
so he is trying to explain how to copy objects
1 2 3 4 5
linkedList one;
linkedlist two;
one = two;
linkedList three = two;
so then he goes onto to pretty much say that this is a bad idea because you are making what's known as a shallow copy of pointers where you assign a second pointer to point to the same memory as the first pointer
for example let's say we have our linkedList class and we write code like this
1 2 3 4 5
linkedList one;
linkedList two;
one = two;
the trouble is that the default assignment operator generates the following code
one.p_head = two.p_head;
and it then shows a diagram with one.p_head and two.p_head pointing to the same value in memory
so I don't understand how they are pointers?? he did not declare them as pointers with the star symbol so how is this considered a "shallow copy" when they are not even pointers :s I'm so confused
The linkedList one/two are not the pointers. p_head is a pointer. That's the problem of shallow copy: You assign unknowingly pointers that are internal to a class.
A deep copy copies all data. So if you were to dynamically allocate memory; on a shallow copy you would copy only a 32 bit pointer to the allocated memory, with a deep copy, you would copy the entire object the pointer is pointing to, so if that allocation was for say a video clip of 70Mb, you would copy that 70Mb, not the pointer.
operator=(const linkedList &ll) // the assignment operator is required
{
...
p_head = new node;
*p_head = *(ll.p_head); // Note that the pointer are dereferenced using *
...
}
thanks guys really makes a world of difference,heres another example and it's quite similar to the example you showed me above it would have been nice If Alex Allain would explain the code he writes in more detail in his book but unfortunatly he doesn't
class LinkedList
{
public:
LinkedList() // constructor
~LinkedList() // destructor
LinkedList& operator= (const LinkedList &other);
void insert (int val); // adds a node
private:
LinkedListNode *p_head;
};
LinkedList& LinkedList::operator= (const LinkedList &other){
// make sure we are not assigning to ourself
// we can just ignore that if it happens
// notice 'this' here to ensure that the other value
// isn't the same address as our object
if(this == &other){
//return this object to keep the chain
// assignments alive
return *this;
}
// before copying over the new values, we need to free the old memory,since it's not longer used
delete p_head;
p_head = NULL;
}
LinkedListNode *p_itr = other.p_head;
while(p_itr != NULL){
insert(p_itr-> val );
}
return *this;
}
I really wish the author broke down the code in detail in the book but this code just confuses me
A) (line 25 - 30)what does he mean by make sure we are not assigning to ourselfs and what does he mean we can just ignore if it happens so why would we use the word this and return *this
B) (line 33 - 36) why do we need to delete (free) the old memory and how is it no longer used?
A: By assigning to ourselves think of the expression a = a. Or in the programming sense Object == Object. There would be no need in copying any contents of the object since it is equal to itself.
1 2 3
Object a = 5;
Object b = 5;
a = b; // No work will be done, a remains the same
B: You must delete memory you allocate because other resources also need to use this memory, such as your internet explorer and system programs. If you programs keeps requesting memory and not freeing what it no longer needs, that memory does not get released until the program closes. This can cause a problem if your program runs for a long time and eats up all your RAM. :]
C: The this keyword and pointer are a special thing in the C++ language. It is a pointer relating to it's own memory address for instance:
1 2 3 4 5 6 7 8
class Object
{
private:
int a;
public:
Object(int val): a(val) {}
Object* Me() { returnthis; }
};
calling Object.Me() will return the address of the Object.
and I understand this but then he goes on to mention
Now,most of the time rather than declaring a stand-alone function for operator=,a class will typically make the operator= function a member function so that operator= can work with private fields of the class(as opposed to just declaring a free-floating function like I did above)
linkedList& operator=(linkedList& lhs,const linkedList& rhs)
The above function is a global function (or as the author calls it a "stand alone function"). Note that it is not qualified by the class name and it takes the both the left hand side and right hand side as arguments. As the author implies, this form can not reference private members of linkedlist unless it were made a friend function.
The more common alternative is to make the the operator = function a member of the linkedlist class.
Note that this form takes only one argument. i.e. the right hand side. The object implied by the this pointer is the left hand side. As stated by the author, as a member function, it has access to private members.
so far I find copying objects with the copy constructors and overloading operators which involve linked lists one of the more complicated subjects in C++