2010-07-21 60 views
6

當我嘗試在窗體類內創建窗體類的對象時,它會發生一個異常,因爲發生了stackoverflow.However,當我聲明方法內的窗體類的對象,它工作正常。代碼如下:在窗體類中的stackoverflow異常

namespace WindowsFormsApplication6 
{ 
    public partial class Form1 : Form 
    { 

     **Form1 f1 = new Form1();**//gives stackoverflow exception....... 

     char[] ar = new char[15]; 
     int flag = 0, end; 
     double val1, val2, res; 
     string oprt; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void masters(object sender, EventArgs e) 
     { 
      ar[i] = char.Parse(((Button)sender).Text); 
      if (char.IsDigit(ar[i])) 
      { 
       if (flag != 0) 
       { 
        if (textBox1.Text == oprt) 
        { 
         textBox1.Clear(); 
        } 

       } 
       else 
       { 
        if (end == 1) 
        { 
         textBox1.Clear(); 
         end = 0; 
        } 
       } 
       Button ansbox = sender as Button; 
       textBox1.Text += ansbox.Text; 

      } 
      else if (char.IsSymbol(ar[i])) 
      { 
       if (textBox1.TextLength != 0) 
       { 
        val1 = double.Parse(textBox1.Text); 
        textBox1.Clear(); 
        Button bt = sender as Button; 
        if (bt != null) 
         textBox1.Text = bt.Text; 
        oprt = bt.Text; 
        // dot.Enabled = true; 
        flag = 1; 
       } 
      } 
     } 





     private void button14_Click(object sender, EventArgs e) 
     { 
      if (textBox1.TextLength != 0) 
      { 
       val2 = double.Parse(textBox1.Text); 
       switch (oprt) 
       { 
        case "+": res = val1 + val2; 
         break; 
        case "-": res = val1 - val2; 
         break; 
        case "*": res = val1 * val2; 
         break; 
        case "/": res = val1/val2; 
         break; 
       } 


       textBox1.Text = res.ToString(); 
       flag = 0; 
       end = 1; 
      } 
     } 
    } 
} 

} 
+7

+1 stackoverflow異常! – Fabian 2010-07-21 14:58:53

回答

4

你當創建Form1將創建Form1的私有實例,所以這是某種無限循環的:

某處在你的代碼中創建您的第一個Form1的實例。 當這個實例創建時,它創建一個Form1的新實例。 這個實例還創建Form1的一個實例,並再次,再等

所以,當一個實例被創建的所有變量都被初始化,當你宣佈他們是這樣的: Form1 f1 = new Form1()這個全自動instatiates形式的新實例。

我建議你不要有你的Form1的新實例,您Form1的內部,但如果你真的需要這種創造,使實例的方法:

更改Form1 f1 = new Form1();Form1 f1;。 並創建一個方法:

public void InstantiateNewForm1Instance() 
{ 
    f1 = new Form1(); 
} 

不過:不調用這個方法在構造函數中!否則你將有同樣的問題:-)

1

表單被實例化,然後它處理私有字段,它實例化form1,然後實例化私有字段(查找form1),然後實例化該對象和進程私人領域,繼續。

所以這就是爲什麼會發生這種情況,而在一個方法中,一個方法只在被調用時執行,沒有內部初始化。

爲什麼在form1中需要另一個同樣形式的實例?

+2

呃......瘋狂? – Lazarus 2010-07-21 15:03:13

2

這是因爲每次你創建類的實例時,它會創建類的另一個實例等等......等等......等等......

換句話說,你嘗試創建類的實例時會有無限遞歸。

您需要添加一些控件,以確定在構建時是否創建了Form1的新實例。一個簡單的(和不完整)的解決辦法是這樣的:

public partial class Form1 : Form 
{ 
    Form1 f1; 

    public Form1() : this(false) 

    public Form1(bool createNewInstance) 
    { 
     if(createNewInstance) 
      f1 = new Form1(); 
     else 
      f1 = null; 
    } 
} 
1

難道是因爲Form1中試圖實例化另一個Form1中這又是試圖實例另一個Form1中等等?

0

如果每個Form1類都包含一個Form1類的新實例,則在嘗試創建一個時,您肯定會遇到堆棧溢出異常。

通過試圖在一張紙上繪製物體,模擬它們在內存中佔據的空間和他們的孩子佔據的空間,可以更清楚地看到它 - 但請記住,每個Form 1必須具有相同的大小!

6

創建Form1的實例會導致f1屬性初始化爲帶有Form1的實例,這會導致f1屬性被初始化爲帶有Form1的實例,從而導致f1屬性被初始化爲Form1的實例這將導致f1屬性被初始化爲Form1的實例,這將導致f1屬性被初始化爲Form1的實例,這將導致f1屬性被初始化爲具有將導致f1屬性爲用Form1的一個實例初始化,這會導致f1屬性被初始化爲一個Form1的實例,這會導致f1屬性被初始化爲一個Form1的實例,這會導致f1屬性被初始化爲一個Form1的實例,導致f1屬性被初始化爲F的一個實例orm1這將導致f1屬性初始化與Form1的實例,這將導致f1屬性被初始化的Form1的實例,將... Stack Overflow!

在該類的一個方法中,'f1'將是本地的,並且只存在於該調用的整個生命週期中。除非您在實例化的Form1上調用相同的方法,否則將不會創建後續的Form1。

1

如果您在Form1的新構造函數中,則已經創建了Form1的一個實例。所以,在創建完成之前,你正在創建另一個,然後那個也一樣。在你的程序加載之前,太多的form1正在堆棧中......溢出堆棧。