torfinna@grim.uio.no (Torfinn Aas) (09/25/89)
I have a linkt list class with a next pointer. This pointer is a pointer to
the next node-obj. in the list.
I want to overload the ++ operator, so that by applying ++ to a node-pointer
it will move the pointer to the next element in the list.
This is what I did:
void node::operator ++ (){
this = next;
}
node* ptr;
//... point ptr to list
(*ptr)++;
This did not advance the pointer ay all. Why not?
I also tried
*ptr++;
but that did not work at all. (because of the precedence I suppose)
Is it not possible to point <this> to another obj. within the obj.?
Torfinn Aas
UiO, Blindern, Norway
beard@ux1.lbl.gov (Patrick C Beard) (09/25/89)
In article <2046@ifi.uio.no> torfinna@grim.uio.no (Torfinn Aas) writes: > >I want to overload the ++ operator, so that by applying ++ to a node-pointer >it will move the pointer to the next element in the list. > >This is what I did: > void node::operator ++ (){ > this = next; > } > > node* ptr; > //... point ptr to list > (*ptr)++; > >This did not advance the pointer ay all. Why not? Because "this" is a hidden argument to the function node::operator++() that is passed by value. It might be the same pointer as ptr, but in multiple inheritance cases, or others I'm not aware of it won't be. It is because "this" is passed by value that you can't alter the original pointer with your overloaded operator. However, you can get the desired behaviour if you overload the "->" operator to point to the node that you have moved to with the "++" operator. Finally, an application for smart pointers! Here's how you might do this: class List { private: // private implementation stuff.. Node* headOList; // the head. Node* currentNode; // the current node that you move forward with ++. public: ListNode(); ~ListNode(); void operator++() { if (currentNode) currentNode = currentNode->next; } void operator--() { if (currentNode) currentNode = currentNode->prev; } void* operator->() { return currentNode->data; } void *data; // dummy element for "smart pointer" to point to. }; While I'm not sure it's perfectly correct (and I leave the implementation of the Node to you), I believe that operators should operate on the list pointer, and not the Node pointers. And if at all possible, you shouldn't give the user of the list any sense of the implementation of the list at all. ------------------------------------------------------------------------------- - Patrick Beard, Macintosh Programmer (beard@lbl.gov) - - Berkeley Systems, Inc. ".......<dead air>.......Good day!" - Paul Harvey - -------------------------------------------------------------------------------
jima@hplsla.HP.COM (Jim Adcock) (09/27/89)
In any case, assignment to this is considered obsolete with 2.0, though still allowed for backward compatibility. Expect C++ compilers to not support assignment to this in the future. Not allowing assignment to this can allow more efficient compilers. For example, consider the following oop style of chaining commands: --------------------------------------------------------------------------- class something { public: something& dothis(); something& dothat(); something& doanotherthing(); }; something& something::dothis(){ /* do something, then */ return *this;} something& something::dothat(){ /* do something, then */ return *this;} something& something::doanotherthing(){ /* do something, then */ return *this;} main() { something I; I.dothis().dothat().doanotherthing(); } --------------------------------------------------------------------------- presently [2.0] compiles on my mot680x0 machine to: global something::dothis() something::dothis() : mov.l 4(%sp),%d0 rts global something::dothat() something::dothat() : mov.l 4(%sp),%d0 rts global something::doanotherthing() something::doanotherthing() : mov.l 4(%sp),%d0 rts global main main: link.w %a6,&-4 jsr _main pea -4(%a6) jsr something::dothis() mov.l %d0,(%sp) jsr something::dothat() mov.l %d0,(%sp) jsr something::doanotherthing() unlk %a6 rts --------------------------------------------------------------------------- but a compiler that doesn't allow assignment to this, and follows a register passing protocol of passing this in d0, could generate the following [better] code: global something::dothis() something::dothis() : rts global something::dothat() something::dothat() : rts global something::doanotherthing() something::doanotherthing() : rts global main main: link.w %a6,&-4 jsr _main mov.l d0,-4(%a6) jsr something::dothis() jsr something::dothat() jsr something::doanotherthing() unlk %a6 rts