Possible Duplicate:
How can a class have a member of its own type, isnt this infinite recursion?
The Code:
public class Test2{
private Test2 subject = new Test2(); //Create Test2 object in Test2
private int num;
}
The Questions:
Why does Java permit the above code to be executed, but C++ doesn't?
Does the code above create infinite number of objects? Since Test2
itself contains a Test2
object which again contains a Test2
object which itself has a Test2
object and so on.
The key difference between the two languages regarding your problem is that Java is a language with reference semantics (with the exception of primitive types), and C++ a language with value semantics that allows reference semantics through references and pointers.
Syntax that looks similar in both language has complete different meanings, when in Java you create a reference (Test2 x = new Test2();
) the equivalent construct in C++ would be using a pointer (Test2 *x = new Test2();
).
A key difference is that it is simple to provide reference semantics on top of value semantics through the use of pointers, but it is impossible to provide value semantics on top of (pure) reference semantics. Some of the implications of this statement include not being able to control the layout of objects in Java in memory or the locality of data (for anything other than primitive types and arrays of primitive types), while on the other direction the finer control of objects in C++ allows you to mimic Java objects.
Re question 2 - if you run this code, you get a StackOverflowException => Yes it creates an inifinite number of objects (well it tries...)
public class Test2 {
private Test2 subject = new Test2(); //Create Test2 object in Test2
public static void main(String[] args) throws Exception {
Test2 t = new Test2();
}
}
subject
here is a reference to an instance of Test2
. If you try to run it, the code will quickly run out of some resource (probably stack space, maybe heap space).
Why does Java permit the above code to be executed but C++ doesn't?
Since 2011, C++ also allows class members to be initalised in their declarations.
However, it wouldn't allow this case: you can only instantiate complete types, and a class type is incomplete within the class definition, so it would have to be initialised in the constructor, or by a call to a function:
class Test;
Test * make_test();
class Test {
// Test is incomplete, so "new Test" is not possible here
Test * test = make_test();
};
// Test is complete, so we can instantiate it here
Test * make_test() {return new Test;}
Java doesn't have a concept of incomplete types, so the class can be instantiated anywhere you're allowed to instantiate any class.
Does the code above create infinite objects?
Yes, trying to instantiate such a class would throw your program into a recursive death spiral.
If you declare subject
as being static
, you would get an eager initialization version of the Singleton pattern, which will not get you to out of resources.
since you can have multiple constructors its allowed.
if you only have one constructor this would indeed result in an infinite loop.
public class Test{
private Test a;
public Test(String s){
this.a=new Test();
}
public Test(){
}
}