C++类与对象深入之构造函数与析构函数详解 对象的初始化和清理生活中我们买的电子产品都基本会有出厂设置在某一天我们不用时候也会删除一些自己信息数据保证安全。C中的面向对象来源于生活每个对象也都会有初始设置以及对象销毁前的清理数据的设置。一构造函数对象的初始化和清理也是两个非常重要的安全问题一个对象或者变量没有初始状态对其使用后果是未知。c利用了构造函数解决上述问题这两个函数将会被编译器自动调用完成对象初始化和清理工作。对象的初始化和清理工作是编译器强制要我们做的事情因此如果我们不提供构造和析构编译器也会提供编译器提供的构造函数和析构函数是空实现。构造函数是一个特殊的成员函数名字与类名相同实例化类对象时由编译器自动调用保证每个数据成员都有一个合适的初始值并且在对象的生命周期内只调用一次构造函数语法类名(){}1.1构造函数的特性构造函数是特殊的成员函数需要注意的是构造函数的名字虽然叫构造但是构造函数的主要任务并不是开空间创建对象而是初始化对象。构造函数特征1. 构造函数没有返回值也不写void2. 函数名称与类名相同3. 构造函数可以有参数因此可以发生重载4. 程序在调用对象时候会自动调用构造无须手动调用,而且只会调用一次123456789101112131415161718192021222324252627282930313233classDate{public:Date(){_year 1;_month 1;_day 1;}Date(intyear,intmonth,intday){_year year;_month month;_day day;}voidPrint(){cout _year - _month - _day endl;}private:int_year;// 年int_month;// 月int_day;// 日};intmain(){Date d1;//调用无参构造d1.Print();Date d2(2022, 5, 15);//调用带参的构造d2.Print();system(pause);return0;}5. 如果类中没有显式定义的构造函数则C编译器会自动生成一个无参的默认构造函数一旦用户显式定义编译器将不再生成。6. 无参的构造函数和全缺省的构造函数都被称为默认构造函数并且默认构造函数只有一个。注意无参构造函数、全缺省构造函数、以及我们没显式写由编译器默认生成的构造函数都可以认为是默认构造函数。即不用传参就可以调用的函数12345678910111213141516171819202122232425262728293031classDate{public:Date(intyear 1,intmonth 1,intday 1)//默认全缺省构造函数{_year year;_month month;_day day;}voidPrint(){cout _year - _month - _day endl;}private:int_year;// 年int_month;// 月int_day;// 日};intmain(){Date d1;d1.Print();Date d2(2022, 5, 15);d2.Print();Date d3(2022);d3.Print();Date d4(2022, 10);d4.Print();system(pause);return0;}1-1-12022-5-152022-1-12022-10-1请按任意键继续. . .7. 默认生成构造函数对于内置类型成员变量不做处理因为编译器默认生成的构造函数都是空实现对于自定义类型成员变量做出处理相当于实例化对象自动调用该类的默认构造函数如下述代码中Date date和A _aa有什么区别呢不都是实例化对象自动调用默认构造函数吗代码示例123456789101112131415161718192021222324252627282930classA{public:A(){cout A() endl;_a 0;}private:int_a;};classDate{public:voidPrint(){cout _year - _month - _day endl;}private:int_year;// 年int_month;// 月int_day;// 日A _aa;};intmain(){Date date;date.Print();system(pause);return0;}A()-858993460--858993460--858993460请按任意键继续. . .默认构造函数不会对自己的变量初始化会对自定义类型处理自定义类型成员会去调用它的默认构造函数因为这里实例化对象也只能调用默认构造函数如果自定义类型的构造函数没有显示定义也会是随机值。接下来我们利用代码详细看看上面这段话示例1默认生成的默认构造函数123456789101112131415161718192021222324252627classStack{public:private:int* _a;int_top;int_capacity;};classMyQueue {public:// 默认生成构造函数就可以用了voidpush(intx) {}intpop() {}private:Stack _st1;Stack _st2;};intmain(){MyQueue q;q.push(1);//Stack st;system(pasue);return0;}上面这段代码是可以编译过的在Myqueue类中只有自定义类型所以我们不需要写构造函数使用默认生成的即可。然后Myqueue类中声明Stack类实例化对象时会去调用Stack类的默认构造函数这里是自动生成的默认构造函数编译通过这里咋们看监视界面由于Stack的默认构造函数是默认生成的同样不会对内置类型成员变量做初始化所以显示是随机值示例2无参默认构造1234567891011121314151617181920212223242526272829303132classStack{public:Stack(){_a nullptr;_top _capacity 0;}private:int* _a;int_top;int_capacity;};classMyQueue {public:// 默认生成构造函数就可以用了voidpush(intx) {}intpop() {}private:Stack _st1;Stack _st2;};intmain(){MyQueue q;q.push(1);//Stack st;system(pasue);return0;}这段代码也是可以编译过的在Myqueue类中只有自定义类型所以我们不需要写构造函数使用默认生成的即可。然后Myqueue类中声明Stack类实例化对象时会去调用Stack类的默认构造函数这里是咋们自己提供的默认构造函数编译通过同样的我们看监视界面由于Stack的默认构造函数是是我们自己提供的同时对内置类型做了初始化所以这里的各个值不再是随机值示例3全缺省默认构造函数