question--function returns class object(comparing C++ & JAVA)

X

Xiaoshen Li

Dear Sir,

I am a little puzzled about a function returning a class object, for
example, suppose I hava a class Money and a method:

Money lastYear(Money aMoney)
{
Money tempMoney;
...
return tempMoney;
}

Because in C++ the RETURNED is actually a new copy of the object(kind of
like passing by value), here a copy of tempMoney is returned, so after
the statement of return, the local & temporary object tempMoney will be
destroyed.

Now, if in JAVA, since always passing by reference, if above code is
Java, the RETURNED is the MEMORY ADDRESS of the object tempMoney. So
after the exit of the function, the object tempMoney refering to is
referenced by other variable. So it stays existing. What happens to the
local & temporary variable tempMoney? Will it be destroyed after the
function has finished?

Another question:
In C++,
Money aMoney, bMoney;
...
bMoney = aMoney;

Now bMoney and aMoney are referring to different but identical objects.

But in JAVA,

bMoney = aMoney;

will make bMoney and aMoney refer to the SAME object. Is this correct?
Can I make assignment("=") in JAVA behaves like in C++?


Thank you very much.
 
E

Eric Sosman

Xiaoshen Li wrote On 12/13/05 13:51,:
Dear Sir,

I am a little puzzled about a function returning a class object, for
example, suppose I hava a class Money and a method:

Money lastYear(Money aMoney)
{
Money tempMoney;
...
return tempMoney;
}

Because in C++ the RETURNED is actually a new copy of the object(kind of
like passing by value), here a copy of tempMoney is returned, so after
the statement of return, the local & temporary object tempMoney will be
destroyed.

Now, if in JAVA, since always passing by reference, if above code is
Java, the RETURNED is the MEMORY ADDRESS of the object tempMoney. So
after the exit of the function, the object tempMoney refering to is
referenced by other variable. So it stays existing. What happens to the
local & temporary variable tempMoney? Will it be destroyed after the
function has finished?

tempMoney is not an object; it is a reference to
a Money object. When the lastYear() method returns,
the tempMoney variable ceases to exist, but nothing
happens to the Money object it once referred to.

In C terms, tempMoney is a pointer and the Money
object is the thing it points to. Destroying the
pointer doesn't destroy the pointed-to object.
Another question:
In C++,
Money aMoney, bMoney;
..
bMoney = aMoney;

Now bMoney and aMoney are referring to different but identical objects.

But in JAVA,

bMoney = aMoney;

will make bMoney and aMoney refer to the SAME object. Is this correct?
Yes.

Can I make assignment("=") in JAVA behaves like in C++?

I don't know C++, but from your description it sounds
like you want a copy of the object that aMoney points to.
Unaided `=' will not do this. If you actually need a copy
(that is, a new Money object initialized with all the same
contents as the old one), the simplest approach is to give
the Money class a "copy constructor" that does the job:

Money(Money oldMoney) {
amount = oldMoney.amount;
currency = oldMoney.currency;
exchangeRate = oldMoney.exchangeRate;
...
}

Now you can write `bMoney = new Money(aMoney)'.

Other possibilities exist, with somewhat different
semantics. You can write `bMoney = aMoney.clone()' if
Money implements the Cloneable interface, and this will
work better if Money has subclasses. However, Cloneable
has some drawbacks and is not something to be added
without careful consideration. You could also serialize
a Money object and then deserialize it to create another,
but that smacks of perversity. And there are probably
more possibilities I haven't thought of. But a copy
constructor is certainly the simplest approach, so use
it if it meets your needs.
 
A

Andrew McDonagh

Xiaoshen said:
Dear Sir,

I am a little puzzled about a function returning a class object, for
example, suppose I hava a class Money and a method:

Money lastYear(Money aMoney)
{
Money tempMoney;
...
return tempMoney;
}

this code means there is a Local Reference called 'tempMoney' which
points to an instance of the Money class (i.e a Money object).

References in Java have scope, the objects they point to do not.

So in the code above, the 'tempMoney' reference certainly does go out of
scope when this method returns. But the Object that the 'tempMoney'
Reference pointed too, does not because they can not.

In Java, when an object has no references pointing to it, it 'becomes
eligible for garbage collection'. Worth Google-ing this term as its a
whole thread of discussion just about that.

Java References are not like C++ References nor Pointers. They don't
point to memory addresses per se. And you certainly can't get or do
pointer arithmetic with them.


Because in C++ the RETURNED is actually a new copy of the object(kind of
like passing by value), here a copy of tempMoney is returned,

There's no copying of the Object that the reference pointer too - its
still the same object. However, a new Reference will be created if the
return value is assigned to a reference.

As in..

Money someMoney = lastYear(otherMoney);

Here 'someMoney' points to the SAME object that the 'tempMoney' pointed
too. But someMoney is a new Reference.

so after the statement of return, the local & temporary object tempMoney will be
destroyed.

no see above
Now, if in JAVA, since always passing by reference, if above code is
Java, the RETURNED is the MEMORY ADDRESS of the object tempMoney.
So after the exit of the function, the object tempMoney refering to is
referenced by other variable. So it stays existing. What happens to the
local & temporary variable tempMoney? Will it be destroyed after the
function has finished?

no see above.

Another question:
In C++,
Money aMoney, bMoney;

In Java we have too....

Money aMoney = new Money();
Money bMoney = new Money();

...
bMoney = aMoney;

Now bMoney and aMoney are referring to different but identical objects.

its been 5 years since I've done any C++ but are you sure about this
statement? Seems wrong to me....

I thought in C++ this means that bMoney is a (C++) reference to aMoney
But in JAVA,

bMoney = aMoney;

will make bMoney and aMoney refer to the SAME object. Is this correct?

yes.

It also means that the object that bMoney reference pointed too, now has
no references pointing to it and so its eligible for garbage collection.
Can I make assignment("=") in JAVA behaves like in C++?

Not sure I understand what you want...
Thank you very much.

No problem glad to help
 
R

ricky.clarkson

Java and C are both pass by value only. However, the possible values
differ.

In Java, you cannot have a 'stack object'. Within a method:
Object object=new Object();

The Object resides on the heap. Only the variable, object, resides on
the stack.

So this is somewhat related to:

void *pointer=malloc(100);

So the *value* passed to a method is the reference (a reference is a
pointer [1] ).

Tony Morris, the guy who wrote JTiger, wrote something on this. [2]

[1]
http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#106237
[2] http://jqa.tmorris.net/faq/GetQAndA.action?qids=37&showAnswers=true
 
J

J. Verdrengh

Now, if in JAVA, since always passing by reference, if above code is Java,
the RETURNED is the MEMORY ADDRESS of the object tempMoney. So after the
exit of the function, the object tempMoney refering to is referenced by
other variable. So it stays existing. What happens to the local &
temporary variable tempMoney? Will it be destroyed after the function has
finished?
Class instances are created on the heap and are therefore not destroyed
after exiting a function.
Local variables (a reference in your case) are stored on the stack and
therefore are destroyed when exiting the function.
When no more references to an instance exist, Java will garbage collect the
instance (==remove it from the heap)
Another question:
In C++,
Money aMoney, bMoney;
..
bMoney = aMoney;

Now bMoney and aMoney are referring to different but identical objects.

But in JAVA,

bMoney = aMoney;

will make bMoney and aMoney refer to the SAME object. Is this correct? yes

Can I make assignment("=") in JAVA behaves like in C++?
yes, you can use bMoney = (Money)aMoney.clone();
See another recent thread of this newsgroup for extra info on using
..clone().
 
X

Xiaoshen Li

In java, what is returned is actually a reference, not exactly the memory
address - but you can see it that way, it can make it easier to understand if
you come from C++

You should remember that in Java, all variables of class types are in fact
references, which are similar (but not identical) to C++ pointers. So, if the
above code were Java, it would be the same as the C++ code:

Money& lastYear(Money *aMoney)
{
Money* tempMoney = new tempMoney();
// ...
return tempMoney;
}

So in java, all references to objects (not primitives) are similar to pointers.
There is no way to have objects like in your C++ code above.

As for the memory issues, the local reference tempMoney gets out of scope (is
deleted) but the object (memory space) it points to remains, and is returned to
the calling function.




No, because (see above) there is no way to make objects like that. Again, if
you look at the above code as if it were Java, it would be translated to C++ as
such:

Money *aMoney, *bMoney;
...
bMoney = aMoney; // both point to the same object in memory


As an aside, using Java references and C++ pointers is more memory efficient
than using C++ objects - so you probably shouldn't be asking for a way to use
C++ style objects in Java anyway :)
Sorry. I cannot understand it. I thought putting a copy constructor
inside java class Money will do the job, as some repliers suggested.

(Java code:)
Money aMoney, bMoney;
aMoney = new Money();
bMoney = new Money(bMoney); //now aMoney, bMoney refer to two identical
but different objects on the heap.

Further, could you explain a little more about "C++ objects" and "C++
pointers"?
(C++ code:)
Money *aMoney = new Money();
Money bMoney;

now aMoney is a pointer pointing to an heap object instance of class
Money. BUT bMoney is an object on stack. Is this correct? bMoney is "C++
object" you called above? Thank you.
 
Z

zero

its been 5 years since I've done any C++ but are you sure about this
statement? Seems wrong to me....

I thought in C++ this means that bMoney is a (C++) reference to aMoney

nope, the statement is correct. It would be a reference if it were:

Money& cMoney = aMoney;

Here you can say cMoney is of type "Money&", which is a reference type.
Note this is quite different from

Money cMoney;
cout << &cMoney; // output the address of cMoney
 
Z

zero

Xiaoshen Li said:
Dear Sir,

I am a little puzzled about a function returning a class object, for
example, suppose I hava a class Money and a method:

Money lastYear(Money aMoney)
{
Money tempMoney;
...
return tempMoney;
}

Because in C++ the RETURNED is actually a new copy of the object(kind of
like passing by value), here a copy of tempMoney is returned, so after
the statement of return, the local & temporary object tempMoney will be
destroyed.

Now, if in JAVA, since always passing by reference, if above code is
Java, the RETURNED is the MEMORY ADDRESS of the object tempMoney. So
after the exit of the function, the object tempMoney refering to is
referenced by other variable. So it stays existing. What happens to the
local & temporary variable tempMoney? Will it be destroyed after the
function has finished?

In java, what is returned is actually a reference, not exactly the memory
address - but you can see it that way, it can make it easier to understand if
you come from C++

You should remember that in Java, all variables of class types are in fact
references, which are similar (but not identical) to C++ pointers. So, if the
above code were Java, it would be the same as the C++ code:

Money& lastYear(Money *aMoney)
{
Money* tempMoney = new tempMoney();
// ...
return tempMoney;
}

So in java, all references to objects (not primitives) are similar to pointers.
There is no way to have objects like in your C++ code above.

As for the memory issues, the local reference tempMoney gets out of scope (is
deleted) but the object (memory space) it points to remains, and is returned to
the calling function.
Another question:
In C++,
Money aMoney, bMoney;
..
bMoney = aMoney;

Now bMoney and aMoney are referring to different but identical objects.

But in JAVA,

bMoney = aMoney;

will make bMoney and aMoney refer to the SAME object. Is this correct?
Can I make assignment("=") in JAVA behaves like in C++?

No, because (see above) there is no way to make objects like that. Again, if
you look at the above code as if it were Java, it would be translated to C++ as
such:

Money *aMoney, *bMoney;
....
bMoney = aMoney; // both point to the same object in memory


As an aside, using Java references and C++ pointers is more memory efficient
than using C++ objects - so you probably shouldn't be asking for a way to use
C++ style objects in Java anyway :)
 
X

Xiaoshen Li

zero said:
For example:

<java code snippet>

class SomeClass
{
private int attribute;

public SomeClass()
{
attribute == -1;
}

public void setAttribute(int i)
{
attribute = i;
}

public int getAttribute()
{
return attribute;
}
}

class Money
{
int amount;
SomeClass someClass;

public Money()
{
amount = 0;
someClass = new someClass(); // attribute = -1;
}

public Money(Money old)
{
this.amount = old.amount; // safe
this.someClass = old.someClass; // dangerous!
}
}

Money aMoney = new Money();
Money bMoney = new Money(aMoney);

bMoney.someClass.setAttribute(5);

if(aMoney.someClass.getAttribute() ==
bMoney.someClass.getAttribute())
System.out.println("Error!");
</java code snippet>

Here you will have two different objects aMoney and bMoney in memory,
however - and this is something a lot of people make mistakes against -
when changing bMoney.someClass you're also changing aMoney.someClass!!

Why? Because aMoney.someClass and bMoney.someClass point to the same
object in memory, even though aMoney and bMoney are different objects.
This is because the copy constructor has an error: it makes the someClass
reference in the new object point to the same memory space as someClass
in the old object.

This is a very dangerous and often overlooked mistake.

I see. I will change the copy constructor of class Money to:
public Money(const Money old)
{
this.amount = old.amount;
this.someClass = new SomeClass(old.someClass);
}

Of course, I need to put a copy constructor inside class SomeClass.

I think this will do the job. Thank you very much!
 
Z

zero

Xiaoshen Li said:
Sorry. I cannot understand it. I thought putting a copy constructor
inside java class Money will do the job, as some repliers suggested.

(Java code:)
Money aMoney, bMoney;
aMoney = new Money();
bMoney = new Money(bMoney); //now aMoney, bMoney refer to two
identical but different objects on the heap.


yes actually that will do it - but you have to be careful if you're using
compound classes (ie classes that contain references to other objects).

For example:

<java code snippet>

class SomeClass
{
private int attribute;

public SomeClass()
{
attribute == -1;
}

public void setAttribute(int i)
{
attribute = i;
}

public int getAttribute()
{
return attribute;
}
}

class Money
{
int amount;
SomeClass someClass;

public Money()
{
amount = 0;
someClass = new someClass(); // attribute = -1;
}

public Money(Money old)
{
this.amount = old.amount; // safe
this.someClass = old.someClass; // dangerous!
}
}

Money aMoney = new Money();
Money bMoney = new Money(aMoney);

bMoney.someClass.setAttribute(5);

if(aMoney.someClass.getAttribute() ==
bMoney.someClass.getAttribute())
System.out.println("Error!");
</java code snippet>

Here you will have two different objects aMoney and bMoney in memory,
however - and this is something a lot of people make mistakes against -
when changing bMoney.someClass you're also changing aMoney.someClass!!

Why? Because aMoney.someClass and bMoney.someClass point to the same
object in memory, even though aMoney and bMoney are different objects.
This is because the copy constructor has an error: it makes the someClass
reference in the new object point to the same memory space as someClass
in the old object.

This is a very dangerous and often overlooked mistake.
Further, could you explain a little more about "C++ objects" and "C++
pointers"?
(C++ code:)
Money *aMoney = new Money();
Money bMoney;

now aMoney is a pointer pointing to an heap object instance of class
Money. BUT bMoney is an object on stack. Is this correct? bMoney is
"C++ object" you called above? Thank you.

Yes that's what I meant. I haven't studies heaps & stacks in detail, so
I kinda make up my own words ;-) Here, bMoney is the name of the actual
object in memory, while aMoney is actually the name of a pointer to an
object in memory. In Java, every variable (except for primitives) is a
pointer to an object - or actually a reference, but it looks a lot like a
pointer to C++ programmers.
 
X

Xiaoshen Li

Andrew said:
the only question is why do you need to do this at all? yes its common
in C++ to have and use a copy constructor, but less so in Java.

You should find yourself needing to clone (which is what you are doing)
only once in a while - not as a standard rule.

Could you elaborate why copy constructor is so common and important in
C++ while in java it is not so important? Thank you very much.
 
A

Andrew McDonagh

zero said:
@news.freedom2surf.net:




nope, the statement is correct. It would be a reference if it were:

Money& cMoney = aMoney;

Here you can say cMoney is of type "Money&", which is a reference type.
Note this is quite different from

Money cMoney;
cout << &cMoney; // output the address of cMoney

oh yes - its coming back now - cheers.
 
A

Andrew McDonagh

Xiaoshen said:
I see. I will change the copy constructor of class Money to:
public Money(const Money old)
{
this.amount = old.amount;
this.someClass = new SomeClass(old.someClass);
}

Of course, I need to put a copy constructor inside class SomeClass.

I think this will do the job. Thank you very much!


the only question is why do you need to do this at all? yes its common
in C++ to have and use a copy constructor, but less so in Java.

You should find yourself needing to clone (which is what you are doing)
only once in a while - not as a standard rule.
 
A

Alun Harford

Xiaoshen Li said:
Could you elaborate why copy constructor is so common and important in C++
while in java it is not so important? Thank you very much.

(I'm not the OP but here goes)

Firstly, I should point out that creating a copy constructor in Java is
"wrong" - you should implement the Cloneable interface and override the
clone() method of Object.

The primary use for copy constructors in C++ is to create a copy of an
object that is passed by value to your function. Since all Java Objects are
passed by reference, this is not required.

Alun Harford
 
A

Andrew McDonagh

Alun said:
(I'm not the OP but here goes)

Firstly, I should point out that creating a copy constructor in Java is
"wrong" - you should implement the Cloneable interface and override the
clone() method of Object.

The primary use for copy constructors in C++ is to create a copy of an
object that is passed by value to your function. Since all Java Objects are
passed by reference, this is not required.

Alun Harford

Thanks! saved me typing!
 
A

Andrew McDonagh

Andrew said:
Thanks! saved me typing!

Aside from this major point of not needing copy constructors in java, we
rarely want to have a cloned object either - sometimes, but rarely.
 
T

Thomas Hawtin

Firstly, I should point out that creating a copy constructor in Java is
"wrong" - you should implement the Cloneable interface and override the
clone() method of Object.

There is only need to implement Cloneable if you are going to use the
Object implementation of clone. There is not a pressing need to make
clone public (or add package private access when you override). Prior to
1.5, using a different method allows a useful return type. Using
Object.clone has dangers (admittedly, as does copying lots of fields one
by one).
The primary use for copy constructors in C++ is to create a copy of an
object that is passed by value to your function. Since all Java Objects are
passed by reference, this is not required.

ObPedantry: It's object references passed by value.

In C++ it's not just passing to your functions where values are copied,
also using, say, the collections of the C++ standard library copies.

Because Java uses garbage collection, the use of immutable types is
trivial. C++ will do implicit copying. In Java where we have types that
fall between immutable values and full-grown "reference objects" with
meaningful identities, then we need to remember to explicitly copy. For
instance when returning a List value object from a public method.

Tom Hawtin
 
R

Roedy Green

Could you elaborate why copy constructor is so common and important in
C++ while in java it is not so important? Thank you very much.

There is no easy way to code them in Java which discourages their use.
I have many times asked for efficient ways to promote and demote
objects.
 
C

Chris Smith

zero said:
In java, what is returned is actually a reference, not exactly the memory
address - but you can see it that way, it can make it easier to understand if
you come from C++

I don't understand what you mean here, zero. Chances are extremely good
that the reference IS exactly the memory address. The relationship
between the words "reference" and "memory address" is not that they are
alternatives to each other, but that a reference is an abstraction
that's very likely (almost certain, in fact) to be implemented as a
memory address.

So depending on whether you're talking within or outside the language
model, it is reasonable to say either that a method returns a reference
or a memory address, and it's almost certainly correct (though not
guaranteed as such by any spec) to say that a reference is a memory
address.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top