类的对象作为类中的实例变量

时间:2012-11-28 14:45:27

标签: java c++ oop reference instance-variables

  

可能重复:
  How can a class have a member of its own type, isnt this infinite recursion?

守则:

public class Test2{
    private Test2 subject = new Test2(); //Create Test2 object in Test2
    private int num;
}

问题:

  1. 为什么Java允许执行上面的代码,但C ++不允许?

  2. 上面的代码是否会创建无限数量的对象?由于Test2本身包含一个Test2对象,该对象又包含一个Test2对象,该对象本身有一个Test2对象,依此类推。

6 个答案:

答案 0 :(得分:17)

两种语言之间关于您的问题的主要区别在于Java是一种具有引用语义的语言(原始类型除外),而C ++是一种具有值语义的语言,它允许通过引用和指针引用语义。

在两种语言中看起来类似的语法具有完全不同的含义,在Java中创建引用Test2 x = new Test2();)时,C ++中的等效构造将是使用指针(Test2 *x = new Test2();)。

一个关键的区别是,通过使用指针在值语义之上提供引用语义很简单,但是不可能在(纯)引用语义之上提供值语义。这个陈述的一些含义包括无法控制内存中Java对象的布局或数据的位置(除了基本类型和基本类型数组之外的任何东西),而在另一个方向上则可以更精细地控制对象在C ++中允许您模仿Java对象。

答案 1 :(得分:13)

问题2 - 如果运行此代码,则会得到StackOverflowException =>是的,它会创建一个无限数量的对象(它会尝试...)

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();
    }
}

答案 2 :(得分:4)

subject这是引用Test2的实例。如果您尝试运行它,代码将很快耗尽某些资源(可能是堆栈空间,可能是堆空间)。

答案 3 :(得分:2)

  

为什么Java允许执行上面的代码但是C ++没有?

自2011年以来,C ++还允许类成员在其声明中获得成功。

但是,它不允许这种情况:您只能实例化完整类型,并且类类型在类定义中是不完整的,因此必须在构造函数中初始化,或者通过调用函数:

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没有不完整类型的概念,因此可以在允许实例化任何类的任何地方实例化该类。

  

上面的代码是否会创建无限对象?

是的,试图实例化这样一个类会使你的程序陷入递归的死亡螺旋。

答案 4 :(得分:0)

如果您将subject声明为static,您将获得Singleton模式的急切初始化版本,这将无法让您从资源中获取。

答案 5 :(得分:0)

因为你可以拥有多个构造函数。 如果你只有一个构造函数,这确实会导致无限循环。

public class Test{
    private Test a;

    public Test(String s){
        this.a=new Test();
    }

    public Test(){

    }

}