[comp.lang.c++] ********

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