当前位置: 首页 > news >正文

C++基础(3)-类的6个默认成员函数

C++的类中,有6个默认成员函数,即使用户不实现,编译器会帮助用户实现。

类的6个默认成员函数:

1、构造函数

2、析构函数

3、拷贝构造函数

4、赋值重载函数

5、const成员函数

6、取地址以及const取地址操作符重载

构造函数

当我们实现一个类后,往往创建出这个类的对象后,首先要对其进行初始化,这一点无论放在哪个类上面,都是要进行的。所以,C++在类中引入构造函数,当类的对象创建出来后,C++编译器会自动调用其构造函数进行初始化工作,这样,用户在创建出对象后,就可以直接使用这个对象,不需要初始化了。

构造函数的职责不是开空间创建对象,是对类实例化的对象进行初始化。

在类中定义了构造函数后,编译器会通过用户实际传递的参数进行匹配适合的构造函数,这个适合的构造函数只能有一个,进行初始化对象。

class Date
{
public:Date(){_year = 2000;_month = 12;_day = 31;}Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1;d1.Print();Date d2(2025,1,1);d2.Print();return 0;
}

如果要调用无参的构造函数时,不可以Date d1()这样写,因为这会让编译器分不清这一行代码是函数声明还是创建类对象。

class Date
{
public:Date(){_year = 2000;_month = 12;_day = 31;}
private:int _year;int _month;int _day;
};int main()
{Date d1(); //ErrorDate d1; //OKreturn 0;
}

构造函数可以支持重载,这样写语法层面上没问题,但是,在创建Date对象时,如果是无参数创建时(Date d1;),此时,编译器就不知道要调用哪个构造函数了,因为这俩构造函数都满足条件,编译器就会报错。

Date()
{_year = 2000;_month = 12;_day = 31;
}
Date(int year = 2020, int month = 1, int day = 1)
{ _year = year;_month = month;_day = day;
}//调用 Date d1;出现Error

即使我们在类中不写构造函数,此时,编译器也会默认生成一个构造函数。默认生成的构造函数:对于内置类型的成员变量不做处理、对于自定义类型的成员变量会去调用其构造函数。

内置类型就是C语言内部自带的类型,比如:int、double、float、指向任何数据类型的指针类型等。自定义类型就是用户自己定义的类型:比如:struct结构体、class类、union联合体类型等。

对内置类型不做处理。

对自定义类型会去调用其自定义类型的构造函数。

这个设计不是很完美,所以在C++11及其以后,支持给类中的内置类型的成员变量赋缺省值。类似于这样:

class AA
{
private:int x=10;int y=20;
};

这样,在进行初始化对象时,调用编译器生成的默认构造函数时,就会将内置类型处理为缺省值,即x初始化为10,y初始化为20。

但是,注意,这里的x和y成员变量还是声明,这个10、20只是给的缺省值,不是定义!!!

默认构造函数分为:

1、用户不写,编译器默认生成的构造函数是默认构造函数。

2、用户写的无参数的构造函数是默认构造函数。

3、用户写的全缺省的构造函数是默认构造函数。

只要不传参数的构造函数,都是默认构造函数。这三种默认构造函数不能同时存在,那样会存在歧义,导致编译器不知道调用哪个,所以只能存在一个。

构造函数的特征:

1、函数名和类名相同

2、无返回值

3、对象实例化时编译器自动调用对应的构造函数进行初始化

4、构造函数可以重载

5、当用户不写构造函数时,编译器会默认生成一个构造函数,在类的对象实例化出来后进行调用,默认成员函数对内置类型可以用其缺省值进行初始化,如果没有给缺省值,就用随机值初始化、对自定义类型去调用其自定义类型的构造函数。

6、当用户写了构造函数时,编译器就不会生成默认构造函数了。

析构函数

构造函数的作用是进行初始化,析构函数的作用是进行销毁、完成资源的清理工作,这里的资源指的是用户自己申请的内存空间,new、malloc的空间,内置类型不需要清理,比如:int、double类型的成员变量,因为这些内置类型是存储在这个类对象所处的函数栈帧中的,当出了作用域后,编译器就会对这块栈帧进行销毁,这里的内置类型的成员变量也会被销毁,而用户手动申请的空间存储在堆上,堆内部开辟的空间只有程序退出时才会被系统进行销毁,如果用户不主动销毁,那么只有等到程序退出的时候,才会被销毁,这里就会出现内存泄漏的问题,所以析构函数的存在是为了防止内存泄露,从而在合适的时机将资源其进行销毁。

class Stack
{
public:Stack(int capacity = 5){_a = (int*)malloc(sizeof(int) * capacity);if (_a == nullptr){perror("malloc error");exit(-1);}_capacity = capacity;_top = 0;}~Stack(){free(_a);_a = nullptr;_top = _capacity = 0;}
private:int* _a;int _top=0;int _capacity;
};
int main()
{Stack s;return 0;
}

调用析构函数之前:

调用析构函数之后:

析构函数特征:

1、函数名是在类名前面加上按位取反操作符~

2、无参数、无返回值

3、一个类只能有一个析构函数。若用户未显示定义,系统会自动生成默认的析构函数。

4、不支持重载。

5、类对象生命周期结束后,C++编译器会自动调用其析构函数。

6、如果用户不写析构函数,编译器会默认生成析构函数,默认生成的析构函数:对内置类型成员变量不做处理,对自定义类型的成员变量会去调用其自定义类型的析构函数。

对于上面Stack的例子,如果不写析构函数,那么_a指向的空间是不会被销毁的,编译器也不知道要销毁多少,多长的空间资源,所以,对于析构函数来说,如果类中手动申请了空间,那么析构函数就很有必要实现。

http://www.dtcms.com/a/415152.html

相关文章:

  • 做营销型网站需要注意哪些点开发小程序费用
  • AI“点亮”萤火虫:边缘机器学习让微光成像走进4K时代
  • 【手撕机器学习 02】手撕算法的基石:精通NumPy与Pandas向量化思维
  • 一种好用开发的轻量级 Markdown 编辑器
  • 网站用户管理系统徐州市城乡建设局网站
  • 花店网站首页模版帝国cms使用教程
  • React-router v6学生管理系统笔记
  • 手写签名太麻烦?智能签名生成器免费实测 智能签名生成器、智能签名生成器使用、免费电子签名工具、Windows 电子签名软件、办公效率工具
  • 建设银行六安市分行网站hreflang wordpress
  • N8N Workflow Collection - 专业级自动化工作流库
  • 有没有专业做特产的网站小企业如何建网站
  • Android 6.0+ 动态权限请求模块,这个模块会包含 权限检查、请求、结果处理 等核心功能,并且支持 单个 / 多个权限请求、权限拒绝后的引导
  • Android -自定义Binding Adapter实战应用
  • 网站优化提升速度网站建设权利义务
  • 【复现】一种基于价格弹性矩阵的居民峰谷分时电价激励策略【需求响应】
  • 【怎么复制cmd命令行里面的文字输出和报错】
  • Oracle体系结构-RECO详解
  • 2025.9.27总结
  • 做网站怎么跟客户谈话搜狗优化好的网站
  • 乐清网站推广公司怎样取消2345网址导航
  • AI时代大数据分布的深入洞察与应用
  • Istio - 开源服务网格平台
  • NLP:关于Bert模型的基础讲解
  • 兰州新区建设局网站地址金华做网站报价
  • seo网站推广龙岩网红餐厅
  • 20252803《Linux内核原理与分析》第三周作业
  • SpringIoC容器对bean的管理
  • 无广告阅读新体验:Reader与cpolar的远程访问方案
  • 集团网站建设行业现状电商网站开发 文献综述
  • 南昌做兼职的网站设计wordpress建站 客户端