2010-07-21 57 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正在堆栈中......溢出堆栈。