一、构造函数与析构函数
C++ 在类中的成员变量不能直接用 需要自己将变量所占的内存地方清零,否则直接用的话 除了赋值外都可能使程序出错,因此为了不让这种情况的发生,C++中专门设计了一种Constructor构造器 即构造函数 与类名相同 无返回类型。而析构函数就是做"清理善后"工作。在超过类的实例的Scope范围,系统就会自动调用该函数。简单来说在构造函数中又有默认构造函数(无参数)和自己定义的构造函数(有参数)之分。拷贝构造函数暂且不说明。下面通过一段代码,及其代码上所指示的标注对构造函数和析构函数的具体使用所一个简单说明,程序源码如下(点开即可)(代码中标注 (1)(2)(3)这样的序号 在注释区会有详细的解释):
1 #include<iostream> 2 using namespace std; 3 class X{ 4 5 public: 6 int x; 7 int *p; 8 X(){} //(1) 9 X(int y);//(2) 10 ~X(); //(3) 11 }; 12 X::X(int y) //注意这里没有void 的返回类型 因为析构和构造函数都没有返回类型 13 { 14 p =new int;//申请资源 (4) 15 x = y; //这实际上称为赋值 而不是初始化 16 cout<<"进入构造函数了其值为:"<<x<<endl; 17 } 18 X::~X() 19 { 20 delete p;//释放资源 21 //(5) 22 cout<<"进入的是变量值为 "<< x<<"的析构函数" <<endl;//可以看出退出构造函数的顺序 23 } 24 int main() 25 { 26 X a(12);//此时将12给了构造函数的形式参数 27 28 { 29 cout<<"进入变量b的scope "<<endl; 30 X b(10); 31 cout<<"退出变量b的Scope"<<endl; 32 } 33 34 return 0; 35 }
注释区:
(1)这样的才是默认构造函数,如果我们没有显示定义构造函数,则编译器就会提供一个默认构造函数称为合成的默认构造函数
(2)构造函数 在实例化的时候自动调用 //注意这里已经不是默认构造函数了
(3)析构函数 在这个类超出scope前 自动调用
(4)可以再构造函数中申请空间 之后再析构函数中释放掉
(5)//这里可以对一些申请的内存资源进行释放 进行操作
//比如delete p 或者delete[]p 这里的P是在构造函数中申请的
注意:
// new int ;
// new int *;
// new int *[10];
// delete p;
// delete[]p; //记住 仅仅new[]时(代表数组形式)才会用这个带括号的(下面的笔记图片中有记载)
试验结果:
结果说明:
定义一个变量的时候,系统会自动的调用构造函数,超出变量的scope范围的时候,系统也会自动的调用析构函数。
补充说明:
如果在以上的代码基础上 ,在main函数中 改为下面的图片,则在编译的时候不会出错,但是运行的时候就会出错。是因为没有调用其他的析构函数导致的程序崩溃。但是在类X声明的内部,构造函数中new 一个数组形式的内存和在析构函数中delete p这样的形式不会出现错误,因为delete会删除p指向的那块内存,不涉及析构函数,所以不会出现错误。具体请看下面的总结
总结:对上面的delete p和delete[]p做的笔记,如下图所示: