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

山西省住房和城乡建设厅网站报名企业网站帮助中心

山西省住房和城乡建设厅网站报名,企业网站帮助中心,做盗版小说网站赚钱嘛,国内网站都要备案吗目录 拷贝构造函数概述 拷贝构造函数特性 拷贝构造函数概述 当我们定义好一个类#xff0c;不做任何处理时#xff0c;编译器会自动生成以下6个默认成员函数#xff1a; 默认成员函数#xff1a;如果用户没有手动实现#xff0c;则编译器会自动生成的成员函数。 同样不做任何处理时编译器会自动生成以下6个默认成员函数 默认成员函数如果用户没有手动实现则编译器会自动生成的成员函数。 同样拷贝构造函数也属于6个默认成员函数而且拷贝构造函数是构造函数的一种重载形式。 拷贝构造函数的功能就如同它的名字——拷贝。我们可以用一个已存在的对象来创建一个与已存在对象一模一样的新的对象。 class Date { public://构造函数Date(){cout Date() endl;}//拷贝构造函数Date(const Date d){cout Date() endl;_year d._year;_month d._month;_day d._day;}//析构函数~Date(){cout ~Date() endl;} private:int _year 0;int _month 0;int _day 0; };void TestDate() {Date d1;//调用拷贝构造创建对象Date d2(d1); }拷贝构造函数特性 拷贝构造函数作为特殊的成员函数同样也有异于常人的特性 拷贝构造函数是构造函数的重载拷贝构造函数的参数只有一个且必须是类类型对象的引用。若使用传值的方式则编译器会报错因为理论上这会引发无穷递归。 错误示例 class Date { public://错误示例//如果这样写编译器就会直接报错但我们现在假设如果编译器不会检查//这样的程序执行起来会发生什么Date(const Date d){_year d._year;_month d._month;_day d._day;} private:int _year 0;int _month 0;int _day 0; }; void TestDate() {Date d1;//调用拷贝构造创建对象Date d2(d1); }当拷贝构造函数的参数采用传值的方式时创建对象d2会调用它的拷贝构造函数d1会作为实参传递给形参d。不巧的是实参传递给形参本身又是一个拷贝会再次调用形参的拷贝构造函数…如此便会引发无穷的递归。 3. 若未显式定义编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝这种拷贝叫做浅拷贝或者值拷贝 class Date { public://构造函数Date(int year 0, int month 0, int day 0){//cout Date() endl;_year year;_month month;_day day;}//未显式定义拷贝构造函数/*Date(const Date d){_year d._year;_month d._month;_day d._day;}*/void print(){cout _year - _month - _day endl;} private:int _year 0;int _month 0;int _day 0; };void TestDate() {Date d1(2023, 3, 31);//调用拷贝构造创建对象Date d2(d1);d2.print(); }有的小伙伴可能会有疑问编译器默认生成的拷贝构造函数貌似可以很好的完成任务那么还需要我们手动来实现吗 答案是当然需要。Date类只是一个较为简单的类且类成员都是内置类型可以不需要。但是当类中含有自定义类型时编译器可就办不了事儿了。 4. 类中如果没有涉及资源申请时拷贝构造函数是否写都可以一旦涉及到资源申请时则拷贝构造函数是一定要写的否则就是浅拷贝 class stack { public:stack(int defaultCapacity10){_a (int*)malloc(sizeof(int)*defaultCapacity);if (_a nullptr){perror(malloc fail);exit(-1);}_top 0;_capacity defaultCapacity;}~stack(){cout ~Stack() endl;free(_a);_a nullptr;_top _capacity 0;}void push(int n){_a[_top] n;}void print(){for (int i 0; i _top; i){cout _a[i] ;}cout endl;} private:int* _a;int _top;int _capacity; };void TestStack() {stack s1;s1.push(1);s1.push(2);s1.push(3);s1.push(4);s1.print();stack s2(s1);s2.print();s2.push(5);s2.push(6);s2.push(7);s2.push(8);s2.print(); }如图所示这段程序的运行结果是程序崩溃了且通过观察发现是在第二次析构时出现了错误。其实出现错误的原因是在第二次析构时对野指针进行free了。 一个小tip多个对象进行析构的顺序如同栈一样先创建的对象后析构后创建的对象先析构。 为什么会出现对野指针进行free呢 原因是对象s1与对象s2中的成员_a指向的是同一块空间。在s2析构完成后这块空间已经被释放此时的s1._a就是野指针。这就是浅拷贝导致的后果。 编译器默认生成的拷贝构造函数是按字节序拷贝的在创建s2对象时仅仅是把s1._a的值赋值给s2._a并没有重新开辟一块与s1._a所指向的空间大小相同内容相同的空间。我们把前者的拷贝方式称为浅拷贝后者称为深拷贝。 当开启监视窗口来观察这一过程我们可以看到s2在进行push时s1的内容也在跟着改变且s1._as2._a 正确做法 class stack { public:stack(int defaultCapacity10){_a (int*)malloc(sizeof(int)*defaultCapacity);if (_a nullptr){perror(malloc fail);exit(-1);}_top 0;_capacity defaultCapacity;}//用户自己定义拷贝构造函数stack(const stack s){_a (int*)malloc(sizeof(int) * s._capacity);if (_a nullptr){perror(malloc fail);exit(-1);}memcpy(_a, s._a, sizeof(int) * s._capacity);_top s._top;_capacity s._capacity;}~stack(){cout ~Stack() endl;free(_a);_a nullptr;_top _capacity 0;}void push(int n){_a[_top] n;}void print(){for (int i 0; i _top; i){cout _a[i] ;}cout endl;} private:int* _a;int _top;int _capacity; };5. 拷贝构造函数典型调用场景 使用已存在对象创建新对象;函数参数类型为类类型对象;函数返回值类型为类类型对象。 为了提高程序效率一般对象传参时尽量使用引用类型返回时根据实际场景能用引用尽量使用引用。
http://www.pierceye.com/news/89079/

相关文章:

  • 自建网站迁移下载wordpress 4.8.1
  • 地方电商门户网站如何建设方案上海企业网站建站模板
  • 网站建设调研南宁做网站推广nnsom
  • 网站建设需求调查杭州有专业做网站的吗
  • 北塘网站制作微信网站建设公司
  • 做网约车网站做男装比较好的网站有哪些
  • 用eclipse做网站模板专业建设网站公司
  • 网站建设机器人重庆做蔬菜配送的网站有哪些
  • wordpress验证google站长手机网站发展
  • 西充企业网站建设怎样备份网站数据库
  • 常用网站架构平面设计师工作内容
  • 徐州市住房和城乡建设局网站首页网站开始开发阶段的主要流程
  • 房产网站建设方案论文网站开发后台框架
  • 12380网站的建设情况网站建设方案产业
  • 做网站sqlserver排序郑州制作微信小程序
  • 网站开发的相关技术安徽网站优化公司价格
  • 杭州市城乡规划局建设局官方网站建设网站免费模板
  • 甘肃省住房与建设厅网站首页公司广告推广方案
  • 网站信息登记表扫描件wordpress 添加商品
  • 何为门户网站沪上家居装修官网
  • 全屏 网站 代码沈阳seo优化排名公司
  • 橙色系网站js特效演示网站
  • 建材公司网站建设方案网站建设材料汇报
  • 淘宝客网站开发上架WordPress获取文章封页
  • 网站中的滑动栏怎么做的如何提高百度权重
  • 浙江省建设职业注册中心网站wordpress 短代码 插件
  • 不同的网站 做301什么是速成网站
  • 聊城做网站做的不错的网络公司深圳网络营销推广中心
  • 找网站公司制作网站烟台企业展厅设计公司
  • 商城网站设计企业群晖 wordpress 配置