先看看一般类的实例化构建顺序
无继承的情况
- 静态字段
- 静态构造方法
- 实例字段
- 实例构造方法
有继承的情况
- 子类(派生类)的静态字段
- 子类(派生类)的静态构造方法
- 子类(派生类)的实例字段
- 父类(基类)的静态字段
- 父类(基类)的静态构造方法
- 父类(基类)的实例字段
- 父类(基类)的实例构造方法
- 子类(派生类)的实例构造方法
这两种情况还是很好理解的。总体来说字段是先于构造函数执行的,不然构造函数拿什么去执行。派生类的字段,和基类的实例先执行,然后再执行派生类的构造函数。这里是,基类的构造函数先执行,然后再执行派生类的构造函数。下面验证下:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
A a = new A();
Console.ReadKey();
}
}
class A: B
{
public A()
{
Console.WriteLine("A");
}
}
class B
{
public B()
{
Console.WriteLine("B");
}
}
}
输出:
B
A
基类的构造函数先执行,然后再执行派生类的构造函数。这里是对的。
C++ 的构造函数和析构函数执行顺序
先调用父类(基类)的构造函数,再调用派生类的构造函数;
变量销毁时:先调用派生类的析构函数,再调用父类(基类)的析构函数。
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<< "基类:AAAAAAAAAAAA" <<endl;
}
~A()
{
cout << "基类:~AAAAAAAAAAAA" << endl;
}
};
class B:public A
{
public:
B()
{
cout<< "派生类:BBBBBBBBB" <<endl;
}
~B()
{
cout << "派生类:~BBBBBBBBB" << endl;
}
};
void solution() //当函数开始时,调用构造函数,当函数结束时,变量对象被销毁
{
B b1;
}
int main()
{
solution();
return 0;
}
输出:
基类:AAAAAAAAAAAA
派生类:BBBBBBBBB
派生类:~BBBBBBBBB
基类:~AAAAAAAAAAAA
看下对象初始化器和构造函数谁先执行
结论:构造函数先于对象初始化器执行,然后,窗体程序的话,对象初始化器先于Load
事件执行。
Form1.cs:
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Console.WriteLine("Fomr1 构造函数!!");
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2() {
Msg = "对象初始化器中赋值!!"
};
form2.Show();
}
}
}
Form2.cs:
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form2 : Form
{
public string Msg { get; set; }
public Form2()
{
InitializeComponent();
Console.WriteLine("Form2 构造函数!!");
this.StartPosition = FormStartPosition.CenterScreen;
this.Msg = "构造函数后执行于对象初始化器!!";
}
private void Form2_Load(object sender, EventArgs e)
{
if (this.Msg == null)
Console.WriteLine("Load 事件先执行!!");
else
Console.WriteLine(this.Msg);
}
}
}
参考: