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

俄罗斯网站域名注册徐州企业网站建设公司

俄罗斯网站域名注册,徐州企业网站建设公司,邯郸市人社局,成都 直播 网站建设目录 拷贝构造函数 概念 特征 赋值运算符重载 运算符重载 赋值运算符重载 ​编辑前置和后置重载 ⭐拷贝构造函数 ⭐概念 拷贝构造函数#xff1a;只有单个形参#xff0c;该形参是对本类类型对象的引用(一般常用const修饰)#xff0c;在用已存 在的类类型对象创建新… 目录 拷贝构造函数 概念 特征 赋值运算符重载 运算符重载 赋值运算符重载 ​编辑前置和后置重载 ⭐拷贝构造函数 ⭐概念 拷贝构造函数只有单个形参该形参是对本类类型对象的引用(一般常用const修饰)在用已存 在的类类型对象创建新对象时由编译器自动调用。 拷贝构造函数是一个特殊的构造函数用于创建一个新的对象其内容与另一个已存在的对象相同。在C中拷贝构造函数通常用于将一个对象的值复制到另一个对象中一个对象存在一个对象不存在以便在程序中进行对象的赋值和传递操作时能够确保对象的内容被正确复制。 ⭐特征 拷贝构造函数也是特殊的成员函数其特征如下: 拷贝构造函数是构造函数的一个重载形式。函数名也与类名相同第一个参数是隐式的this第二个参数是被拷贝的对象如果我们自己实现了拷贝构造函数也要自己实现一个构造函数否则会报错如图拷贝构造函数的参数只有一个且必须是类类型对象的引用如果使用传值方式编译器直接报错因为会引发无穷递归调用。C规定自定义类型传值传参时都会调用它的拷贝构造因为传值传参时形参相当于一份拷贝如果拷贝构造函数也是用传值的形式写的那么它会继续寻找真正的拷贝构造函数造成无穷递归传值的后果若未显式定义编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对内置类型成员按内存存储按字节序完成拷贝自定义类型成员调用它的拷贝构造函数事实上最后还是对内置类型做处理这种拷贝叫做浅拷贝或者值拷贝。 class Time { public:Time(){_hour 1;_minute 1;_second 1;}Time(const Time t){_hour t._hour;_minute t._minute;_second t._second;cout Time::Time(const Time) endl;} private:int _hour;int _minute;int _second; }; class Date { public:void Print(){cout _year - _month - _day endl;} private:// 基本类型(内置类型)int _year 1970;int _month 1;int _day 1;// 自定义类型Time _t; }; int main() {Date d1;d1.Print();// 用已经存在的d1拷贝构造d2此处会调用Date类的拷贝构造函数// 但Date类并没有显式定义拷贝构造函数则编译器会给Date类生成一个默认的拷贝构造函数Date d2(d1);d2.Print();return 0; } 注意在编译器生成的默认拷贝构造函数中内置类型是按照字节方式直接拷贝的而自定义类型是调用其拷贝构造函数完成拷贝的。 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了还需要自己显式实现吗 当然像日期类这样的类是没必要的。那么下面的类呢验证一下试试 // 这里会发现下面的程序会崩溃掉这里就需要深拷贝去解决。 typedef int DataType; class Stack { public:Stack(size_t capacity 10){_array (DataType*)malloc(capacity * sizeof(DataType));if (nullptr _array){perror(malloc申请空间失败);return;}_size 0;_capacity capacity;}void Push(const DataType data){// CheckCapacity();_array[_size] data;_size;}~Stack(){if (_array){free(_array);_array nullptr;_capacity 0;_size 0;}} private:DataType* _array;size_t _size;size_t _capacity; }; int main() {Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0; } 注意类中如果没有涉及资源申请时拷贝构造函数是否写都可以一旦涉及到资源申请时则拷贝构造函数是一定要写的否则就是浅拷贝 拷贝构造函数典型调用场景· 使用已存在对象创建新对象· 函数参数类型为类类型对象· 函数返回值类型为类类型对象   class Date { public:Date(int year, int month, int day){cout Date(int,int,int): this endl;}Date(const Date d){cout Date(const Date d): this endl;}~Date(){cout ~Date(): this endl;} private:int _year;int _month;int _day; }; Date Test(Date d) {Date temp(d);return temp; } int main() {Date d1(2022, 1, 13);Test(d1);return 0; } 为了提高程序效率一般对象传参时尽量使用引用类型返回时根据实际场景能用引用 尽量使用引用 ⭐赋值运算符重载 ⭐运算符重载 C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其 返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数类似。函数名字为关键字operator后面接需要重载的运算符符号operator。函数原型返回值类型 operator操作符(参数列表)注意 不能通过连接其他符号来创建新的操作符必须是C/C语法中存在的操作符比如operator重载操作符必须有一个类类型参数有一个参数是作为this指针隐式传递的不需要写出来用于内置类型的运算符其含义不能改变例如内置的整型不能改变其含义作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this.* :: sizeof ?: . 注意以上5个运算符不能重载。 下面实现一个全局的operator class Date { public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}//private:int _year;int _month;int _day; }; bool operator(const Date d1, const Date d2) {return d1._year d2._year d1._month d2._month d1._day d2._day; } void Test() {Date d1(2018, 9, 26);Date d2(2018, 9, 27);cout (d1 d2) endl; } 这里会发现运算符重载成全局的就需要成员变量是公有的那么问题来了封装性如何保证 这里其实可以用友元解决或者干脆重载成成员函数。 下面写一个运算符重载成成员函数的写法 class Date { public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}// bool operator(Date* this, const Date d2)// 这里需要注意的是左操作数是this指向调用函数的对象bool operator(const Date d2){return _year d2._year; _month d2._month _day d2._day;} private:int _year;int _month;int _day; }; ⭐赋值运算符重载 赋值运算符重载格式 参数类型const T传递引用可以提高传参效率返回值类型T返回引用可以提高返回的效率有返回值目的是为了支持连续赋值例如(ij)10最后i10如果返回的不是引用则不能实现这个效果检测是否自己给自己赋值返回 *this 要符合连续赋值的含义 class Date { public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}Date(const Date d){_year d._year;_month d._month;_day d._day;}Date operator(const Date d){if (this ! d)//防止对自己赋值提高效率{_year d._year;_month d._month;_day d._day;}//这里有返回值才能符合连续赋值//如果返回的不是引用则还会调用拷贝构造创建一个对象返回的是一个新的对象副本。//如果返回的是引用则不会调用拷贝构造return *this;} private:int _year;int _month;int _day; }; int main() {Date d1(2024, 2, 3);Date d2(2024, 2, 10);Date d3(2024, 10, 3);d3 d2 d1;} 赋值运算符只能重载成类的成员函数不能重载成全局函数 class Date { public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}int _year;int _month;int _day; }; // 赋值运算符重载成全局函数注意重载成全局函数时没有this指针了需要给两个参数 Date operator(Date left, const Date right) {if (left ! right){left._year right._year;left._month right._month;left._day right._day;}return left; } // 编译失败 // error C2801: “operator ”必须是非静态成员 原因 赋值运算符如果不显式实现编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了故赋值运算符重载只能是类的成员函数。 用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。 注意内置类型成员变量是直接赋值的而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。 class Time { public:Time(){_hour 1;_minute 1;_second 1;}Time operator(const Time t){if (this ! t){_hour t._hour;_minute t._minute;_second t._second;}return *this;} private:int _hour;int _minute;int _second; }; class Date { private:// 基本类型(内置类型)int _year 1970;int _month 1;int _day 1;// 自定义类型Time _t; }; int main() {Date d1;Date d2;d1 d2;return 0; } 既然编译器生成的默认赋值运算符重载函数已经可以完成字节序的值拷贝了还需要自己实 现吗当然像日期类这样的类是没必要的。那么下面的类呢验证一下试试 // 这里会发现下面的程序会崩溃掉这里就需要深拷贝去解决。 typedef int DataType; class Stack { public:Stack(size_t capacity 10){_array (DataType*)malloc(capacity * sizeof(DataType));if (nullptr _array){perror(malloc申请空间失败);return;}_size 0;_capacity capacity;}void Push(const DataType data){// CheckCapacity();_array[_size] data;_size;}~Stack(){if (_array){free(_array);_array nullptr;_capacity 0;_size 0;}} private:DataType* _array;size_t _size;size_t _capacity; }; int main() {Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0; } 注意如果类中未涉及到资源管理赋值运算符是否实现都可以一旦涉及到资源管理则必须要实现。 ⭐前置和后置重载 在C中前置和后置运算符可以被重载为类的成员函数或全局函数。重载前置运算符时需要返回引用以允许连续的递增操作。而重载后置运算符时需要返回一个临时对象以保持原始值的副本而为了区分两个函数后置的重载函数会有一个int类型的形参实际上可以不用传递编译器会自动识别。 class Date { public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}// 前置返回1之后的结果// 注意this指向的对象函数结束后不会销毁故以引用方式返回提高效率Date operator(){_day 1;return *this;}// 后置// 前置和后置都是一元运算符为了让前置与后置形成能正确重载// C规定后置重载时多增加一个int类型的参数但调用函数时该参数不用传递编译器//自动传递// 注意后置是先使用后1因此需要返回1之前的旧值故需在实现时需要先将this保存一份然后给this 1// 而temp是临时对象因此只能以值的方式返回不能返回引用Date operator(int){Date temp(*this);_day 1;return temp;} private:int _year;int _month;int _day; }; int main() {Date d;Date d1(2022, 1, 13);d d1; // d: 2022,1,13 d1:2022,1,14d d1; // d: 2022,1,15 d1:2022,1,15return 0; } 前置 返回1之后的结果 注意this指向的对象函数结束后不会销毁故以引用方式返回提高效率 后置 前置和后置都是一元运算符为了让前置与后置形成能正确重载C规定后置重载时多增加一个int类型的参数但调用函数时该参数不用传递编译器自动传递 注意后置是先使用后1因此需要返回1之前的旧值故需在实现时需要先将this保存一份然后给this 1而temp是临时对象因此只能以值的方式返回不能返回引用 ___________________________________________________________________________________ ⭐感谢你的阅读希望本文能够对你有所帮助。如果你喜欢我的内容记得点赞关注收藏我的博客我会继续分享更多的内容。⭐
http://www.w-s-a.com/news/552032/

相关文章:

  • 软件开发设计制作网站下载自己怎么做视频收费网站
  • 江苏省建设安全协会网站天津网站建设哪家公司好
  • 资源类网站怎么做的网站上线准备工作
  • 长沙专业网站建设怎么做企业建站公司服务
  • 肇庆市有限公司网站建设手机直接看的网站有哪些
  • 织梦修改网站后备份英语作文模板高中
  • 个人网站域名用什么好上海公司拍沪牌需要什么条件
  • 网站建设 保密做网站赚钱交税
  • 食品建设网站前的市场分析进出口网站贸易平台有哪些
  • php商城网站建设个人网站用什么服务器
  • 如何做好品牌网站建设方案网站开发的学习
  • 网站开发 管理方案wordpress怎么搭建微博
  • 有哪些ui的设计网站网上商城网站建设设计方案
  • iis中怎样配置网站绑定运城可以做网站的公司
  • 品牌网站建设开发价格dedecms电影网站模板
  • 网站设计外包合同帝国网站后台认证码错误
  • 网站设计公司深圳怎么免费做公司网站
  • 90设计网站几次是什么意思swipe类网站
  • 安康微网站建设网站域名使用费用
  • 网站建设执招标评分表微信代理网站模板
  • ps做网站分辨率自适应地方网站盈利
  • 免费自助小型网站专业网站建设组织
  • 猎聘网网站建设目标查看别人wordpress主题
  • 免费建设网站入驻网站备案不能更新吗
  • 个人网站制作代码西安建筑类公司
  • 网站备案要营业执照吗网站建设如何记账
  • 新手学做网站难吗外包服务商
  • 公司网站建设的项目工作分解结构wordpress插件后端页面
  • 四川省建设人才网站2018南京专业建站
  • ppt制作网站推荐seo教程百度网盘