构造函数与析构函数
构造函数
1、什么构造函数
类、结构、联合中的特殊成员函数,与类名、结构名、联合名同的成员函数,没有返回值。
class 类名 { public: 类名(参数列表) { } };
2、何时调用构造函数
当创建类对象时(实例化对象)会自动调用构造函数。
int main(int argc,const char* argv[]) { // 调用无参构造 Student stu; Student* stup = new Student; // 调用有参构造 Student stu1(10010,"hehe",'w',18,98); Student* stup1 = new Student(10011,"xixi",'m',20,95); // 调用有参构造,c11语法标准才支持,-std=c++11 Student stu2 = {10010,"hehe",'w',18,98}; return 0; }
3、在构造函数中应该做什么
构造函数负责创建使用对象的环境,一般构造函数中负责:
1、给成员变量初始化
2、给指针成员分配内存
3、从文件、网络、数据库加载数据
4、完成一些准备工作
4、实现构造函数要注意的问题
在创建类对象时,一定会调用构造函数,如果类中没有显式实现构造函数,编译器会自动生成一个无参的什么都不做的构造函数。
如果显式实现了有参构造函数,那么编译器就不会再生成无参构造。
注意:在使用new[] 创建n个对象时,无法保证给所有的类对象都单独提供参数,去调用有参构造,那么必然需要调用无参构造,此时如果没有显式实现无参构造,编译就会出错。
方法1:
class Student { public: Student() {} // 极简无参构造 };
方法2:
给有参构造函数的所有成员都设置默认形参,当需要调用无参构造时,会自动使用默认参数调用有参构造。
// 无参构造未必无参 class Student { ... public: Student(int _id=0,const string& _name="",char _sex='w',short _age=0,float _score=0) { id = _id; name = _name; sex = _sex; age = _age; score = _score; cout << "我是有参构造" << endl; } };
5、explicit关键字的作用
如果类中有单参的构造函数,那么它的参数类型数据就能隐藏提升为类对象,如果不使用该功能,可以在单参构造函数的前面加 explicit 关键字,参数类型数据就不能再隐藏提升为类对象。
总结:explicit关键字的作用就是禁止单参构造函数的类型提升功能。
#include <iostream> using namespace std; class Test { int num; public: [explicit] Test(int _num) { num = _num; } }; void func(Test t) { cout << "我被调用了" << endl; } int main(int argc,const char* argv[]) { func(1234); }
析构函数:
1、什么析构函数
类、结构、联合中的特殊成员函数,在类名、结构名、联合的前面加~,就是析构函数,没有返回也没有参数。
struct Student { int id; string name; char sex; short age; float score; public: Student(void) { cout << "我是无参构造函数" << endl; } Student(int _id,const string& _name,char _sex,short _age,float _score) { id = _id; name = _name; sex = _sex; age = _age; score = _score; cout << "我是有参构造" << endl; } ~Student(void) { cout << "我是析构函数" << endl; } };
2、在析构函数中应该做什么
析构函数负责对象销毁时的收尾工作,一般构造函数中负责:
1、释放指针成员指向的堆内存
2、往文件中、数据库保存数据
3、何时调用析构函数
1、当类对象离开它所在的作用域时,系统会自动销毁类对象,并自动调用析构函数。
#include <iostream> using namespace std; struct Student { int id; string name; char sex; short age; float score; public: Student(void) { cout << "我是无参构造函数" << endl; } Student(int _id,const string& _name,char _sex,short _age,float _score) { id = _id; name = _name; sex = _sex; age = _age; score = _score; cout << "我是有参构造" << endl; } ~Student(void) { cout << "我是析构函数" << endl; } }; int main(int argc,const char* argv[]) { do{ // 当创建类对象时,自动调用构造函数,当对象离开它的作用域时,会自动调用析构函数 Student stu; }while(0); cout << "-----------" << endl; }
2、当使用delete或delete[] 释放堆内存上的类对象时,会自动调用析构函数(必须使用delete释放)。
#include <iostream> using namespace std; struct Student { int id; string name; char sex; short age; float score; public: Student(void) { cout << "我是无参构造函数" << endl; } Student(int _id,const string& _name,char _sex,short _age,float _score) { id = _id; name = _name; sex = _sex; age = _age; score = _score; cout << "我是有参构造" << endl; } ~Student(void) { cout << "我是析构函数" << endl; } }; int main(int argc,const char* argv[]) { // 使用new 或 new[] 在堆内存上创建类对象时会自动调用构造函数 Student* stup = new Student; Student* stus = new Student[10]; // 类对象的个数,也是执行构造、析构函数的次数 cout << *((int*)stus-1) << endl; // 使用delete 或 delete[] 释放堆内存上的类对象时会自动调用析构函数 delete stup; delete[] stus; // 注意:使用new创建的就使用delete释放,使用new[]创建的就使用delete[]释放,不能混用 return 0; }
4、析构函数要注意的问题
如果没有显式实现析构函数,那么编译器会自动生成一个什么都不做的析构函数。
如果构造函数中使用new、malloc分配的堆内存,就一定要显式实现析构函数,并在析构函数中释放堆内存,否则就会造成内存泄漏。
标签:无参,调用,函数,与析构,c++,析构,Student,构造函数 From: https://blog.csdn.net/zzt_is_me/article/details/142035567