2012-11-28 27 views
9

Powiel możliwe:
How can a class have a member of its own type, isnt this infinite recursion?Przedmiot klasy jako zmiennej instancji wewnątrz klasy

kodu:

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

na pytania:

  1. Dlaczego Java pozwala na wykonanie powyższego kodu, ale C++ go nie obsługuje?

  2. Czy powyższy kod tworzy nieskończoną liczbę obiektów? Ponieważ sam obiekt Test2 zawiera obiekt Test2, który ponownie zawiera obiekt Test2, który sam ma obiekt Test2 i tak dalej.

+1

Pytanie nr 1: Ponieważ kod to Java, a nie C++. –

+1

@JohnDibling: Przypuszczalnie przez "C++" pytanie oznacza "równoważny kod napisany w C++". –

+1

@MikeSeymour: Domyślam się, że moje pytanie brzmi, co OP * uważa * odpowiednik kodu? –

Odpowiedz

4

subject o to odniesienia do wystąpienia Test2. Jeśli spróbujesz go uruchomić, kod szybko zabraknie jakiegoś zasobu (prawdopodobnie stosu, może miejsca na sterty).

13

Re pytanie 2 - jeśli uruchomić ten kod, otrzymasz StackOverflowException => Tak tworzy liczbę inifinite obiektów (dobrze, że próbuje ...)

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

dobre wyjaśnienie. +1 – Juvanis

0

Jeśli zadeklarujesz subject jako static dostaniesz gorliwą wersję inicjalizacyjną wzoru Singleton, która nie pozwoli ci wydostać się z zasobów.

+0

Hej, możesz wyjaśnić nieco, w jaki sposób deklarowanie zmiennej jako statycznej nie spowoduje jej przekształcenia w spiralę rekursywną – light

0

ponieważ można mieć wielu konstruktorów jest dozwolone. jeśli masz tylko jeden konstruktor, to rzeczywiście spowoduje nieskończoną pętlę.

public class Test{ 
    private Test a; 

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

    public Test(){ 

    } 

} 
2

Dlaczego Java pozwalają powyższy kod do wykonania, ale C++ nie?

Od 2011 roku C++ pozwala również na inicjalizację członków klas w swoich deklaracjach.

Jednakże nie pozwoliłoby to na taki przypadek: można utworzyć tylko wystąpienia pełne typy, a typ klasy jest niekompletny w definicji klasy, więc musiałby zostać zainicjowany w konstruktorze lub wywołaniu funkcji :

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 nie ma koncepcji niekompletnych typów, więc klasa może być tworzona w dowolnym miejscu, w którym możesz utworzyć instancję dowolnej klasy.

Czy powyższy kod tworzy nieskończone obiekty?

Tak, próba utworzenia takiej klasy rzuciłaby Twój program w rekurencyjną spiralę śmierci.

+0

+1 dla * rekursywnej spirali śmierci * – Walter

15

Kluczową różnicą między dwoma językami w odniesieniu do twojego problemu jest to, że Java jest językiem z semantyką odniesienia (z wyjątkiem typów pierwotnych), a C++ - językiem z semantyką wartości, która umożliwia odniesienie do semantyki poprzez referencje i wskaźniki.

Składnia że wygląda podobną zarówno w języku posiada kompletne różne znaczenia, gdy w Javie utworzyć odniesienie (Test2 x = new Test2();) równowartość konstrukt w C++ byłby za pomocą wskaźnika (Test2 *x = new Test2();).

Kluczową różnicą jest to, że łatwo jest zapewnić semantykę odniesienia na bazie semantyki wartości za pomocą wskaźników, ale niemożliwe jest zapewnienie semantyki wartości na wierzchu (czystej) semantyki odniesienia. Niektóre z implikacji tego stwierdzenia obejmują brak możliwości kontrolowania układu obiektów w Javie w pamięci lub lokalizacji danych (dla niczego innego niż prymitywne typy i tablice typów pierwotnych), natomiast z drugiej strony lepsza kontrola obiektów w C++ pozwala naśladować obiekty Java.

+3

Mogło być więcej niż 10 głosów w górę. Dzięki za krótki, ale bardzo przejrzysty opis. –

+2

Doskonała odpowiedź! Nikt inny nie dał żadnego rozsądnego wyjaśnienia. Nie sądzę, żeby wielu programistów Javy (jeśli w ogóle) to rozumiało. Do tego pytania potrzebna jest wiedza na temat C++ i Java. – duleshi

Powiązane problemy