Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Java (http://www.velocityreviews.com/forums/f30-java.html)
-   -   why no copy constructor in java? (http://www.velocityreviews.com/forums/t148758-why-no-copy-constructor-in-java.html)

Xiaoshen Li 12-22-2005 11:49 AM

why no copy constructor in java?
 
Dear All,

Sorry for coming back to the old topic. I really cannot understand what
some people has said before. Here I am not interested in clone(), sorry.

In C++, without copy constructor,

MyClass Obj_1 = new MyClass(args);
MyClass Obj_2 = Obj_1;

will make Obj_1 and Obj_2 share the same private object if MyClass has a
private variable which is class type. C++ textbooks say that this
behaviour(shallow copying) is usually un-acceptable. So we need to
provide our own copy constructor, to make sure Obj_1 and Obj_2 have the
identical, but separate private object(deep copying).

In JAVA,
MyClass Obj_1 = new MyClass(args);
MyClass Obj_2 = Obj_1;

will make Obj_1 and Obj_2 two names( two references ) for the same
object. JAVA is happy and accepts such behaviour. It seems to me it is
shallow copying in C++.

My questions is: why C++ cannot accept the shallow copying and JAVA can
and is happy to live with it?

Thank you very much.


Danno 12-22-2005 03:43 PM

Re: why no copy constructor in java?
 
Huh?
Your Obj_1 and Obj_2 are referencing the same object. There is no
copying involved whatsoever. Furthermore, your definition of shallow
vs. deep copy is far different from mine.. There are no copy
constructors in java, you can use the Prototype design pattern.


Stefan Schulz 12-22-2005 03:52 PM

Re: why no copy constructor in java?
 
On Thu, 22 Dec 2005 11:49:47 +0000, Xiaoshen Li wrote:


> In JAVA,
> MyClass Obj_1 = new MyClass(args);
> MyClass Obj_2 = Obj_1;


Which is actually much more like

MyClass *Obj_1 = new MyClass(args);
MyClass *Obj_2 = Obj_1;

Which involves no copying of the actual object living somewhere in the
heap at all.

Java is a funny beast. It has no pointers, except that everything that is
not a primitive is one. A java reference is actually a "polite pointer"
which disallows a lot of the unsafe operations (such as reinterpret_cast,
or pointer arithmetics).

HTH
Stefan

--
You can't run away forever,
But there's nothing wrong with getting a good head start.
--- Jim Steinman, "Rock and Roll Dreams Come Through"



zero 12-22-2005 06:19 PM

Re: why no copy constructor in java?
 
Xiaoshen Li <xli6@gmu.edu> wrote in news:doegn6$36s9$1@osf1.gmu.edu:

> Dear All,
>
> Sorry for coming back to the old topic. I really cannot understand
> what some people has said before. Here I am not interested in clone(),
> sorry.
>
> In C++, without copy constructor,
>
> MyClass Obj_1 = new MyClass(args);
> MyClass Obj_2 = Obj_1;
>
> will make Obj_1 and Obj_2 share the same private object if MyClass has
> a private variable which is class type. C++ textbooks say that this
> behaviour(shallow copying) is usually un-acceptable. So we need to
> provide our own copy constructor, to make sure Obj_1 and Obj_2 have
> the identical, but separate private object(deep copying).
>
> In JAVA, MyClass Obj_1 = new MyClass(args);
> MyClass Obj_2 = Obj_1;
>
> will make Obj_1 and Obj_2 two names( two references ) for the same
> object. JAVA is happy and accepts such behaviour. It seems to me it is
> shallow copying in C++.
>


No, it is not shallow copying. It is in fact, like you said, two
references to *the same* object. Shallow copying in C++ means getting
two references to *two different* (but identical) objects.

The Java way is more like getting a C++ reference to the same object,
which is somewhat unusual, but not "usually unacceptable". Compare
this:

<java>
MyClass obj1 = new MyClass(args); // reference (pointer) to new object
MyClass obj2 = obj1; // reference to same object (no copying)
</java>

<C++>
MyClass obj1(args); // original object (not a pointer or reference!)
MyClass &obj2 = obj1; // reference to same object (no copying)
MyClass obj3 = obj1; // new but identical object (shallow copy)
</C++>

<C++>
MyClass *obj1(args); // pointer (reference) to new object
MyClass *obj2 = obj1; // pointer to the same object (no copying)
</C++>

As you can see, java is much more like the second C++ example, not the
first.
In C++ obj3 is created using the default copy constructor, and hence is a
shallow copy of obj1. In Java there is no default copy constructor - if
you want to copy an object you need to define your own copy constructor,
which could be a shallow or deep copy, depending on how you code it. The
more common way is to use clone though - but here too shallow or deep
copy depends on your own implementation.

<java>
MyClass obj3 = new MyClass(obj1); // copy constructor must be defined
MyClass obj4 = obj1.clone(); // clone must be defined
</java>

-- Beware the False Authority Syndrome

Jean-Francois Briere 12-22-2005 09:51 PM

Re: why no copy constructor in java?
 
By the way, in C++ it's more like:

MyClass Obj_1(args);
MyClass Obj_2 = Obj_1;

Regards


AndyRB 12-23-2005 12:15 AM

Re: why no copy constructor in java?
 
Xiaoshen Li wrote:
> Dear All,
>
> Sorry for coming back to the old topic. I really cannot understand what
> some people has said before. Here I am not interested in clone(), sorry.
>
> In C++, without copy constructor,
>
> MyClass Obj_1 = new MyClass(args);
> MyClass Obj_2 = Obj_1;


The above is incorrect it should either be:
MyClass * Obj_1 = new MyClass(args);
MyClass * Obj_2 = Obj_1;
Here only the pointer value is copied, both pointers will then point to
the same object.
or
MyClass Obj_1 = MyClass(args);
MyClass Obj_2 = Obj_1;
Here either the default memberwise shallow copy will be performed or
maybe a deep copy if the default copy constructor has been overridden.
>
> will make Obj_1 and Obj_2 share the same private object if MyClass has a
> private variable which is class type.

If MyClass has a pointer to allocated data and the class performs the
default memberwise shallow copy then Obj_1 and Obj_2 will both have
pointers pointing to the same data. This is the basic issue regarding
shallow copying of objects (where this sharing of a resource is not
desired or not intended).

> C++ textbooks say that this
> behaviour(shallow copying) is usually un-acceptable. So we need to
> provide our own copy constructor, to make sure Obj_1 and Obj_2 have the
> identical, but separate private object(deep copying).


>
> In JAVA,
> MyClass Obj_1 = new MyClass(args);
> MyClass Obj_2 = Obj_1;
>
> will make Obj_1 and Obj_2 two names( two references ) for the same
> object. JAVA is happy and accepts such behaviour. It seems to me it is
> shallow copying in C++.


In the above only the reference is copied and not the underlying
object, however, this doesn't necessarily create any issues as the
garbage collector is able to track when all references to the object
no-longer exist and know when the object's memory can be reclaimed. The
problem occurs when a copy results in more than one object sharing a
resource and both objects acting as though they are the sole owner of
that resource, i.e. they have not been designed to share the resource
or maybe the sharing was unintentional...
>
> My questions is: why C++ cannot accept the shallow copying and JAVA can
> and is happy to live with it?


The issue mainly crops up with value semantics (and particularly where
objects are passed-by-value) because the default copy-semantics only
performs a shallow copy, for example...
MyClass Foo()
{
MyClass Obj_1 = MyClass(args);
return Obj_1;
}
Imagine MyClass has a dynamic buffer and performs a shallow copy to the
object that will be returned from function foo. Obj_1 will then be
destroyed and, assuming the destructor does what it should and
deallocates the buffer, the pointer in the returned object will have
become invalidated since it was pointing to the dynamic buffer which
has now been deallocated.

If you change foo to use reference rather than value semantics, and
therefore behave more like you would expect in Java, the issue no
longer exists as no copying of the object will take place :-

std::auto_ptr<MyClass> Foo()
{
std::auto_ptr<MyClass> Obj_1 = new MyClass(args);
return Obj_1;
}
>
> Thank you very much.



AndyRB 12-23-2005 12:32 AM

Re: why no copy constructor in java?
 
zero wrote:
> Xiaoshen Li <xli6@gmu.edu> wrote in news:doegn6$36s9$1@osf1.gmu.edu:
>
> > Dear All,
> >
> > Sorry for coming back to the old topic. I really cannot understand
> > what some people has said before. Here I am not interested in clone(),
> > sorry.
> >
> > In C++, without copy constructor,
> >
> > MyClass Obj_1 = new MyClass(args);
> > MyClass Obj_2 = Obj_1;
> >
> > will make Obj_1 and Obj_2 share the same private object if MyClass has
> > a private variable which is class type. C++ textbooks say that this
> > behaviour(shallow copying) is usually un-acceptable. So we need to
> > provide our own copy constructor, to make sure Obj_1 and Obj_2 have
> > the identical, but separate private object(deep copying).
> >
> > In JAVA, MyClass Obj_1 = new MyClass(args);
> > MyClass Obj_2 = Obj_1;
> >
> > will make Obj_1 and Obj_2 two names( two references ) for the same
> > object. JAVA is happy and accepts such behaviour. It seems to me it is
> > shallow copying in C++.
> >

>
> No, it is not shallow copying. It is in fact, like you said, two
> references to *the same* object. Shallow copying in C++ means getting
> two references to *two different* (but identical) objects.

I don't think this is a good description of shallow copying as it can
also describe deep copying. In fact the issue of shallow copying is
that you end up with two references/pointers to *the same* object.
>
> The Java way is more like getting a C++ reference to the same object,
> which is somewhat unusual, but not "usually unacceptable". Compare
> this:
>
> <java>
> MyClass obj1 = new MyClass(args); // reference (pointer) to new object
> MyClass obj2 = obj1; // reference to same object (no copying)
> </java>
>
> <C++>
> MyClass obj1(args); // original object (not a pointer or reference!)
> MyClass &obj2 = obj1; // reference to same object (no copying)
> MyClass obj3 = obj1; // new but identical object (shallow copy)

Or depending on the copy constructor.
MyClass obj3 = obj1; //new but identical object (deep copy)

> </C++>
>
> <C++>
> MyClass *obj1(args); // pointer (reference) to new object
> MyClass *obj2 = obj1; // pointer to the same object (no copying)
> </C++>
>
> As you can see, java is much more like the second C++ example, not the
> first.
> In C++ obj3 is created using the default copy constructor, and hence is a
> shallow copy of obj1. In Java there is no default copy constructor - if
> you want to copy an object you need to define your own copy constructor,
> which could be a shallow or deep copy, depending on how you code it. The
> more common way is to use clone though - but here too shallow or deep
> copy depends on your own implementation.
>
> <java>
> MyClass obj3 = new MyClass(obj1); // copy constructor must be defined
> MyClass obj4 = obj1.clone(); // clone must be defined
> </java>
>
> -- Beware the False Authority Syndrome



zero 12-23-2005 01:24 AM

Re: why no copy constructor in java?
 
"AndyRB" <xandyrb@hotmail.com> wrote in
news:1135297979.431293.254290@g43g2000cwa.googlegr oups.com:

> zero wrote:
>>
>> No, it is not shallow copying. It is in fact, like you said, two
>> references to *the same* object. Shallow copying in C++ means
>> getting two references to *two different* (but identical) objects.

>
> I don't think this is a good description of shallow copying as it can
> also describe deep copying. In fact the issue of shallow copying is
> that you end up with two references/pointers to *the same* object.


I wasn't trying to define shallow copying. I merely wanted to explain
that after a shallow copy you have two references to different (yes
different, not the same, albeit identical) objects. If the object is a
compound object then the references inside both objects will be to the
same object/memory space. But the original object and its copy are not
the same.

>>
>> <C++>
>> MyClass obj1(args); // original object (not a pointer or
>> reference!) MyClass &obj2 = obj1; // reference to same object (no
>> copying) MyClass obj3 = obj1; // new but identical object (shallow
>> copy)

>
> Or depending on the copy constructor.
> MyClass obj3 = obj1; //new but identical object (deep copy)


Only if you define your own copy constructor. The default copy
constructor is a shallow copy. This is fine for non-compound objects,
but not for compound objects. Hence the whole problem with shallow
copying: people not defining a copy constructor for compound objects.

This problem does not exist in Java because there is no default copy
constructor and clone is protected. If you want a copy of an object you
need to create a copy constructor or implement clone, both of which
protect you from forgetting to implement the copy constructor, as often
happens in C++. Of course it doesn't protect you from writing bad copy
code.

--
Beware the False Authority Syndrome

AndyRB 12-23-2005 01:03 PM

Re: why no copy constructor in java?
 
zero wrote:
> "AndyRB" <xandyrb@hotmail.com> wrote in
> news:1135297979.431293.254290@g43g2000cwa.googlegr oups.com:
>
> > zero wrote:
> >>
> >> No, it is not shallow copying. It is in fact, like you said, two
> >> references to *the same* object. Shallow copying in C++ means
> >> getting two references to *two different* (but identical) objects.

> >
> > I don't think this is a good description of shallow copying as it can
> > also describe deep copying. In fact the issue of shallow copying is
> > that you end up with two references/pointers to *the same* object.

>
> I wasn't trying to define shallow copying. I merely wanted to explain
> that after a shallow copy you have two references to different (yes
> different, not the same, albeit identical) objects.

Yes this is true, but the same is also true for a deep copy.
> If the object is a
> compound object then the references inside both objects will be to the
> same object/memory space.

Yes and it is this that is the important point that distinguishes a
shallow from a deep copy.
> But the original object and its copy are not
> the same.
>
> >>
> >> <C++>
> >> MyClass obj1(args); // original object (not a pointer or
> >> reference!) MyClass &obj2 = obj1; // reference to same object (no
> >> copying) MyClass obj3 = obj1; // new but identical object (shallow
> >> copy)

> >
> > Or depending on the copy constructor.
> > MyClass obj3 = obj1; //new but identical object (deep copy)

>
> Only if you define your own copy constructor. The default copy
> constructor is a shallow copy. This is fine for non-compound objects,
> but not for compound objects. Hence the whole problem with shallow
> copying: people not defining a copy constructor for compound objects.


Sure, but in Java any object which contains another object is a
compound object. Most of time in c++ this is not the case and the
default copy constructor works fine, even where member objects will
need to perform a deep copy, example:
class SomeObj
{
std::vector<SomeCompoundObj> array_;
//Some other functions, but no user defined copy constructor.
}

SomeObj Obj1;
SomeObj Obj2(Obj1);
In the above the default copy constructor works fine because vector
performs a deep copy as does each SomeCompoundObj in the array.
>
> This problem does not exist in Java because there is no default copy
> constructor and clone is protected. If you want a copy of an object you
> need to create a copy constructor or implement clone, both of which
> protect you from forgetting to implement the copy constructor, as often
> happens in C++.

Forgetting to implement the copy constructor sounds like a very poorly
designed class to me. If they forgot to implement the copy constructor
(or to disable it completely) it is most probably not the only thing
they forgot. Of course, both cloning and copy constructors in Java have
their own gotchas.
> Of course it doesn't protect you from writing bad copy
> code.

Sure, you can never protect a bad programmer from themselves.

Another important difference is that Java doesn't have implicit
copying, however, it is easier to correctly implement copying or
cloning in c++ than Java (IMHO).

>
> --
> Beware the False Authority Syndrome



zero 12-23-2005 06:17 PM

Re: why no copy constructor in java?
 
"AndyRB" <xandyrb@hotmail.com> wrote in news:1135342995.115424.168520
@g44g2000cwa.googlegroups.com:

> Another important difference is that Java doesn't have implicit
> copying, however, it is easier to correctly implement copying or
> cloning in c++ than Java (IMHO).


Why do you think that? The only part of copying that I think is easier in
C++ than in Java is that in C++ the * syntax clearly shows when you're
working with pointers. The lack of a specific syntax in Java can make you
forget that every class-type variable is a reference - especially if you
come from C++.

--
Beware the False Authority Syndrome


All times are GMT. The time now is 09:40 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.