[comp.lang.c++] C++ 2.0 Question -- Whats wrong with this code ??

mtoy@sgi.com (Michael Toy) (10/17/89)

1	class Base {
2	public:
3	BaseClass();
4	};
5	extern TakesOne(BaseClass*&);
6	BaseClass::BaseClass()
7	{
8		BaseClass *equalsThis = this;
9		TakesOne(equalsThis);
10		TakesOne(this);
11	}

This causes C++2.0 to tell me "reference to const object" on line 10
Other than the workaround in lines 8&9, how would I write line
10 so that the compiler liked it?  Clearly I am missing some
simple thing, it seems like this should work.

Michael Toy

sakkinen@tukki.jyu.fi (Markku Sakkinen) (10/18/89)

In article <981@odin.SGI.COM> mtoy@sgi.com (Michael Toy) writes:
>
>1	class Base {
>2	public:
>3	BaseClass();
>4	};
>5	extern TakesOne(BaseClass*&);
>6	BaseClass::BaseClass()
>7	{
>8		BaseClass *equalsThis = this;
>9		TakesOne(equalsThis);
>10		TakesOne(this);
>11	}
>
>This causes C++2.0 to tell me "reference to const object" on line 10
>Other than the workaround in lines 8&9, how would I write line
>10 so that the compiler liked it?  Clearly I am missing some
>simple thing, it seems like this should work.

According to the reference manual, 'this' is a _constant_ pointer
(to the current class object) in Release 2.0, which it wasn't
in previous releases. Thus you really need your workaround.
As an alternative, if your function TakesOne will not modify its
argument, I think you can declare
	extern TakesOne(BaseClass*const&);
Then line 10 should be legal.

By the way, I think this change in C++ 2.0 is very good for preventing
some puzzling errors, even if some completely good code will also get
bitten by the incompatibily between releases. In fact, let's take a look
at a situation similar to your example:
Some ordinary member function (not a constructor) calls TakesOne,
and accesses some data member of the current object after that.
It must then use the original value of 'this' - therefore
the above workaround is necessary anyway. In older versions of C++,
one can inadvertently get 'this' itself changed.

The original example does concern a constructor, however.
Assignment to 'this' in constructors and destructors for the purpose
of programmer-controlled memory allocation and deallocation was
a badly structured hack to start with. In Release 2.0 it has been
replaced by the possibility to redefine the operators 'new' and
'delete', which is much better and cleaner. Moreover, I suspect
that the older translators require an explicit assignment operation
for 'this' within the constructor function itself in order to
recognise the purpose; calling another function to do the trick
would then not do (but I am not quite sure about this).

Markku Sakkinen
Department of Computer Science
University of Jyvaskyla (a's with umlauts)
Seminaarinkatu 15
SF-40100 Jyvaskyla (umlauts again)
Finland

frei@mez.e-technik.uni-bochum.de (Matthias Frei) (10/19/89)

mtoy@sgi.com (Michael Toy) writes:


>1	class Base {
>2	public:
>3	BaseClass();
>4	};
>5	extern TakesOne(BaseClass*&);
  ...
>10		TakesOne(this);
>11	}

>This causes C++2.0 to tell me "reference to const object" on line 10

Well, "this" is a const pointer to an object. If you pass "this" to
TakesOne() is a reference, it could be manipulated outside of 
the class base, possibly leading to inconsistencies.

You can avoid it by declaring
  extern TakesOne(const BaseClass* &)

-- 
   Matthias Frei			| Snail-mail:
					| Microelectronics Center
frei@mez.e-technik.uni-bochum.de  	| University of Bochum, W-Germany
frei%rubmez@unido.BITNET		| D-4630 Bochum, P.O.-Box 102143

pcg@aber-cs.UUCP (Piercarlo Grandi) (10/20/89)

In article <1532@tukki.jyu.fi> sakkinen@jytko.jyu.fi (Markku Sakkinen) SAKKINEN@FINJYU.bitnet (alternative) writes:

    [ ... ] According to the reference manual, 'this' is a _constant_ pointer
    (to the current class object) in Release 2.0, which it wasn't
    in previous releases. [...]
    
    Assignment to 'this' in constructors and destructors for the purpose
    of programmer-controlled memory allocation and deallocation was
    a badly structured hack to start with. In Release 2.0 it has been
    replaced by the possibility to redefine the operators 'new' and
    'delete', which is much better and cleaner. [ ... ]

It has occurred to me that if BS had hit upon the idea of having overloadable
'new' and 'delete' earlier, instead of the assign-to-this-in-constructor hack,
'this' should have been a reference. Now it is a constant pointer, which
is nearly the same, except for the use of '->' instead of '.' to access
members.

I have been thinking also that if 'this' were made a reference, then it would
be possible to dispense with the concept of member procedure entirely;
any 'friend' of a class with a first parameter of type reference to that
class could be invoked indifferently as

		a_friend(obj,arg1,arg2)

or

		obj.a_friend(arg1,arg)

etcetera, which is similar to what is possible in POP-II. Naturally it would
be possible to allow the latter syntax also for non friends, but I opine that
it ought to be reserved only to friends.
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

pcg@aber-cs.UUCP (Piercarlo Grandi) (10/20/89)

In article <1152@aber-cs.UUCP> I have just written:

    I have been thinking also that if 'this' were made a reference,
    then it would be possible to dispense with the concept of member
    procedure entirely; any 'friend' of a class with a first parameter
    of type reference to that class could be invoked indifferently as

		a_friend(obj,arg1,arg2)

    or

		obj.a_friend(arg1,arg)

I forgot to observe that obviously this would eliminate not just the need
for the concept of member procedure, but also the idea of having 'this' at
all as a distinguished entity, which is even better, given its somewhat
peculiar nature.
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

wmm@sdti.com (William M. Miller) (10/24/89)

In article <1152@aber-cs.UUCP> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes:
>It has occurred to me that if BS had hit upon the idea of having overloadable
>'new' and 'delete' earlier, instead of the assign-to-this-in-constructor hack,
>'this' should have been a reference.

Actually, it's my understanding that the reason "this" is a pointer instead
of a reference is that "this" predates references in the evolution of the
language and that there were already too many programs depending on "this"
as a pointer for it to be changed to a reference.
-- 
Non-disclaimer:  My boss and I always see eye-to-eye (every time I look in
the mirror).

wmm@sdti.sdti.com