Re: still crabby about copy constuctor craziness

From: J. Romano (jl_post_at_hotmail.com)
Date: 07/30/04


Date: 30 Jul 2004 03:03:07 -0700

use63net@yahoo.com (Unknown Poster) wrote in message news:<c62e93ec.0407281337.405e1686@posting.google.com>...

> Anyway, this means that a user of a class doesn't
> know if a copy constructor will be called unless he/she knows if
> the mutator has been explicitly overloaded. Simply unacceptable.

   I don't think it's unacceptable. When the copy constructor gets
called is the business of the programmer who wrote the class. If the
class writer wrote the class well, then the user of the class doesn't
have to concern him/herself with when the copy constructor gets called
or if a mutator has been explicitly overloaded.

   Consider the Math::BigInt package. Over the years, there have been
different implementations of this class. Old versions of Math::BigInt
would autogenerate certain mutators (like "++" and "--"), but the
newest version explicitly overloads them (for efficiency's sake).
Calls to Math::BigInt's copy constructor will happen in one version
where it will not happen in the other. Yet the output is the same,
meaning that a programmer that uses Math::BigInt does not need to know
about Math::BigInt's internals like when the copy constructor will be
called or when a mutator has been explicitly overloaded. There is
nothing unacceptable about this.

> Now, this is just wrong, at least in my environment - page 354:
>
> "The ++$a operation can be autogenerated ... However, this does not
> trigger the copying behavior that a real ++ operator would."
>
> My ++ is autogenerated. If it did NOT cause copying then $a == $b
> after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.
>
> Likewise, again on page 357:
> "$copy = $original; $copy = $copy + 1;
> then no copying occurs ..."
>
> Again, $copy is one more than $original, so copying certainly did occur.

   No, you are mistaken. Copying DID NOT occur. Examine the
following lines carefully:

      $a = $b;
      ++$a;

When the '++' operator is autogenerated, these lines are equivalent
to:

      $a = $b;
      $a = $a + 1;

which DOES NOT call the copy constructor. Instead, the function used
for overloading the '+' operator is called, which normally creates a
new object, populates that object from $a and 1, then returns that new
object, which then gets assigned to $a WITHOUT ever modifying $b. In
other words, no copy of $b was every made or needed (which is why I
said that you are mistaken when you claim that copying certainly did
occur).

   Confusing? A little. That's exactly why I posted a write-up
explaining this exact issue. I even posted the title of this write-up
("Regarding copy constructors and mutators") to you, and even included
a link to it. It seems like you didn't read it, so I invite you to
read it again so that your confusion about this subject can be cleared
up. In case you missed the link the first time around, here it is
again:

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=b893f5d4.0406261126.2e1e23ab%40posting.google.com

   And if you want the exact excerpt that deals with this topic
(without having to look for it), here it is (paraphrased to fit your
example):

=== Beginnining of excerpt ===

The line:

      ++$a;

was treated as if it was:

      $a = $a + 1;

making it so that the function used for '+', and not for '++', was
used. The
function used for '+' does NOT mutate (or change) any parameter passed
in. Instead, that method creates a new object, modifies its value,
and returns that instance. This mutates the new object but it doesn't
affect either of the values passed in. Because of this, '+' isn't
considered by Perl to be a mutator, so it will not call the copy
constructor (and will not give an error if a copy constructor doesn't
exist). It just simply creates a new object from $a and 1 and assigns
it back to $a, making $a lose its original object reference.

CLARIFICATION:
If '+=' is used on a shared reference when '+=' is OVERLOADED, it WILL
call the copy constructor. But if it is AUTOGENERATED (from '+'), it
WILL NOT call the copy constructor, because '+' has no need for one.

The same goes for '++'. If it's not overloaded, Perl is smart enough
to autogenerate by converting "$a++" to "$a = $a + 1" (which doesn't
need the copy constructor) to give you exactly what you'd expect.

=== End of excerpt ===

   Basically, what Anno Siegel wrote in an earlier post was absolutely
correct:

> > If you don't intend to overload mutators, don't worry about it.
> > Understanding "=" is not essential to understanding overloading.
> > It is a workaround for a nasty side-effect of overloading mutators.

So unless you plan to overload mutators, don't worry about it at all.
(There is nothing unacceptable about that.)

> Maybe this mess will be fixed in Perl 6. Otherwise, there's always Java -
> no such thing as a copy constructor, and no operator overloading.

   Maybe this "mess" will be understood when you get around to reading
the write-up I posted (intended for the Perl community and anyone
confused (like I was) about "Copy Constructor Crazyness"). You are
one of the people I posted that write-up for, so please read it before
criticizing this aspect of Perl again.

   Hopefully this will clear the issue for you.

   -- Jean-Luc



Relevant Pages

  • Re: Copy Constructor Craziness
    ... There is no copy constructor involved at all. ... because I don't see any justification for this autogeneration. ... If you're overloading a mutator, there needs to be a copy ...
    (comp.lang.perl.misc)
  • Re: IsNumber function
    ... I've never cared what type of data gets passed to it in a VBA function and have used a variant...which basically is what you did there with the overloading. ... The disadvantage of this is that widening also takes system resources and in my opinion is poor practice, since it creates code that can be hard to read or debug. ... Stefan's code also used widening (from auto-boxed primitives up to Object) and you see that folks are complaining about it. ... I also added a trick where I declared the default constructor private, thus preventing the user from accidentally calling a constructor that did nothing. ...
    (comp.lang.java.help)
  • Re: default parameters
    ... every permutation of default params in a C++ constructor, ... can someone explain the reasoning behind why it does not? ... overloading, and which is indeed what people do today, but yes, you?re ... If you do overloads, let?s say you have void f, and ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Overloading new and delete in C++.
    ... > In most tutorials on overloading 'new', they usually put malloc in the ... > malloc doesn't call the constructor and free won't call the destructor.. ...
    (comp.lang.cpp)

Loading