2012-10-05 110 views
-1

我有個問題要問你們。爲什麼Class實例會覆蓋另一個實例

我已經以下所示的類:

public class Node 
     { 
      public int Kova1;    // Kova 1 
      public int Kova2;    // Kova 2 
      public int Kova3;    // Kova 3 

      public int ActionNo;   // Yapılan İşlem 

      public Node(int kova1, int kova2, int kova3, int actionNumber) 
      { 
       Kova1 = kova1; 
       Kova2 = kova2; 
       Kova3 = kova3; 
       ActionNo = actionNumber; 
      } 

      public Node(int kova1, int kova2, int kova3) 
      { 
       Kova1 = kova1; 
       Kova2 = kova2; 
       Kova3 = kova3; 
      } 

      public Node() 
      { 
      } 

      public Node AnneNode; 
     } 

並且這些功能:

public void CocukNodeOlustur(LinkedList<Node> Acik, LinkedList<Node> Kapali, Node temp) 
{ 
    Node cocukState; 

    Node temp2 = temp; 

    for (int i = 0; i < 12; i++) 
    { 
     cocukState = YeniStateOlustur(temp, i); 

     if ((ActionKontrol(cocukState)) && (GoalBulundu(Acik, Kapali, cocukState)) && 
     ((cocukState.Kova1 != temp2.Kova1) && (cocukState.Kova2 != temp2.Kova2) && (cocukState.Kova3 != temp2.Kova3))) 
     { 
      cocukState.AnneNode = temp; 
      Acik.AddFirst(temp); 
     } 
    } 
} 

public Node YeniStateOlustur(Node s, int j) 
{ 
    int tempKova1, tempKova2, tempKova3; 

    Node yeniCocuk = new Node(); 

    yeniCocuk = s; 
    yeniCocuk.ActionNo = j; 

    // Gelen numaraya göre uygulanan işlemin seçimi yapılıyor. 
    switch (j) 
    { 
     case 0: 
      { 
       yeniCocuk.Kova1 += (3 - yeniCocuk.Kova1); 
       yeniCocuk.Kova2 += 0; 
       yeniCocuk.Kova3 += 0; 
      } 
      break; 
     case 1: 
      { 
       yeniCocuk.Kova1 += 0; 
       yeniCocuk.Kova2 += (5 - yeniCocuk.Kova2); 
       yeniCocuk.Kova3 += 0; 
      } 
      break; 
    } 

    return yeniCocuk; 
} 

在主函數

  Node temp = new Node(); 

      while (!(Acik.Count == 0)) 
      { 
       p.CocukNodeOlustur(Acik, Kapali, temp); 
       Kapali.AddLast(temp); 
      } 

所以當我調試我的程序時,我看到每當代碼跳轉到YeniStateOlustur()函數時,程序中的所有Node實例都受到YeniStateOlustur()中的更改的影響。 看來函數中的實例覆蓋了節點類的所有實例。

我不明白爲什麼會發生?

我該如何克服這個問題?

我最好的問候和sory的長期職位。

+3

「我最好的問候和長期的帖子」 - 爲什麼你不縮短呢?你已經給出了*方式*比你需要的更多的代碼 - 一個簡短但完整的例子會更容易處理。 –

+0

@JonSkeet我很喜歡我不能讓它更容易:/ –

+1

我相信你*可以使它變得更簡單...我懷疑你只是沒有嘗試過。你認爲你真的需要所有的代碼來證明這個問題嗎?你有沒有嘗試刪除多餘的位,直到它沒有*但顯示混亂的行爲?您向我們呈現了大約250行代碼,但沒有指明要實現的內容,只是對實際發生的內容進行了非常模糊的描述。 –

回答

1

問題是所有節點都是相同的實例。您的示例代碼僅包含「新節點()」兩次,在第二種情況下(在方法YeniStateOlustur中),新實例立即被丟棄。因此,該函數返回傳遞給它的同一個節點:

public Node YeniStateOlustur(Node s, int j) 
{ 
    int tempKova1, tempKova2, tempKova3; 

    Node yeniCocuk = new Node(); 

    yeniCocuk = s; 

    //... 

    return yeniCocuk;  
}  

在該方法中CocukNodeOlustur,所有的節點變量指向同一個節點:

public void CocukNodeOlustur(LinkedList<Node> Acik, LinkedList<Node> Kapali, Node temp) 
{ 
    // here, temp == temp 
    Node cocukState; 
    // now, temp == temp and cocukState is uninitialized. 
    Node temp2 = temp; 
    // now, temp == temp, temp2 == temp, and cocukState is uninitialized. 

    for (int i = 0; i < 12; i++) 
    { 
     cocukState = YeniStateOlustur(temp, i); 
     // now, temp == temp, temp2 == temp, and cocukState == temp 

     if ((ActionKontrol(cocukState)) && (GoalBulundu(Acik, Kapali, cocukState)) && 
     ((cocukState.Kova1 != temp2.Kova1) && (cocukState.Kova2 != temp2.Kova2) && (cocukState.Kova3 != temp2.Kova3))) 
     { 
      cocukState.AnneNode = temp; 
      Acik.AddFirst(temp); 
     } 
    } 
} 

您的代碼似乎假定該節點是值類型(結構),但它顯然是一個引用類型(類)。如果你不確定這種差異,你應該退後一步,做一些閱讀和實驗。

快速修復可能是將Node的聲明更改爲結構,但我會建議不要這樣做。用結構編程可能非常棘手,如果你理解結構和類之間的差異是不穩定的,那就更是如此。

+0

所以我應該寫節點cocukState = new Node(); ? –

+0

@Un_NatMenDim你會在哪裏寫這個?它會如何幫助?只要你調用'cocukState = YeniStateOlustur(temp,i);',cocukState就會指向temp。它在調用之前指向什麼並不重要,也不管它是初始化的還是未初始化的。 – phoog

+0

如果我使用struct類型,我不能寫「公共節點AnneNode」。這是不允許的。我很困惑。 –