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

本地网站建设需要什么app下载安装免费下载t

本地网站建设需要什么,app下载安装免费下载t,国内最新的新闻,杭州新闻最新消息新闻一:类的六个默认成员函数 如果一个类中什么成员都没有#xff0c;简称为空类。空类中并不是什么都没有#xff0c;任何类在什么都不写时#xff0c;编译器会自动生成以下6个默认成员函数。默认成员函数#xff1a;用户没有显式实现#xff0c;编译器会生成的成员函数称为…一:类的六个默认成员函数 如果一个类中什么成员都没有简称为空类。空类中并不是什么都没有任何类在什么都不写时编译器会自动生成以下6个默认成员函数。默认成员函数用户没有显式实现编译器会生成的成员函数称为默认成员函数 二:构造函数 引出: 在类中我们可以自己定义出它的初始化函数 Init (),但是每次需要调用这个函数,有点麻烦 那有没有什么方法可以让对象在创建时就可以完成初始化呢? 答:构造函数就可以解决这个问题 构造函数概念:         构造函数是一个特殊的成员函数名字与类名相同,创建类类型对象时由编译器自动调用以保证每个数据成员都有 一个合适的初始值并且在对象整个生命周期内只调用一次,需要注意的是,构造函数虽然名称叫构造但是构造函数的主要任务并不是开空间创建对象而是初始化对象 构造函数特性:  构造函数有以下特征: 1. 函数名与类名相同。2. 无返回值。3. 对象实例化时编译器自动调用对应的构造函数。4. 构造函数可以重载 5. 如果类中没有显式定义构造函数则C编译器会自动生成一个无参的默认构造函数一旦用户显式定义编译器将不再生成 情景一: 类内没有定义构造函数,编译器会自动生成一个无参构造函数 class Date { private:int _year;int _month;int _day; }; void TestDate() {Date d1; // 类没有显式定义构造函数,编译器会自动生成一个无参构造函数 } 情景二: 类内定义了自己的构造函数,则编译器就不会生成无参构造函数了,对象的初始化只能使用自己定义的构造函数 6. 无参的构造函数和全缺省的构造函数都称为默认构造函数并且默认构造函数只能有一个。注意无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数都可以认为 是默认构造函数。 class Date { public:// 无参构造函数Date(){_year 2024;_month 10;_day 1;}//带参构造函数Date(int year, int month, int day){_year year;_month month;_day day;}//缺省参数形式Date(int year2024, int month10, int day1){_year year;_month month;_day day;} private:int _year;int _month;int _day; }; void TestDate() {Date d1; // 调用无参构造函数 } 如代码所示,由于同时定义出了无参构造函数和全缺省构造函数,虽然他们满足函数重载,语法没有问题,但他们两个都属于默认构造函数,当创建对象时,编译器会不知道调用哪个而导致编译失败 对编译器自动生成的构造函数的理解  不实现构造函数的情况下编译器会生成默认的构造函数。但是看起来默认构造函数又没什么用d对象调用了编译器生成的默认构造函数但是d对象_year/_month/_day依旧是随机值。也就说在这里编译器生成的默认构造函数并没有什么用 C把类型分成内置类型(基本类型)和自定义类型。 内置类型就是语言提供的数据类型如int/char...自定义类型就是我们使用class/struct/union等自己定义的类型 编译器自动生成的默认构造函数对内置类型确实不做处理,其主要功能是管理类中的自定义类型。当类中存在自定义类型时,默认构造函数会调用该自定义类型的默认构造函数实现初始化 注意C11 中针对内置类型成员不初始化的缺陷又打了补丁即内置类型成员变量在 类中声明时可以给默认值。 三:析构函数 析构函数与构造函数功能相反析构函数不是完成对对象本身的销毁局部对象销毁工作是由 编译器完成的。而对象在销毁时会自动调用析构函数完成对象中资源的清理工作 特性: 析构函数是特殊的成员函数其特征如下 析构函数名是在类名前加上字符 ~无参数无返回值类型 一个类只能有一个析构函数。若未显式定义系统会自动生成默认的析构函数。注意析构函数不能重载 对象生命周期结束时C编译系统系统自动调用析构函数如果类中没有申请资源时析构函数可以不写直接使用编译器生成的默认析构函数比如Date类有资源申请时一定要写否则会造成资源泄漏比如Stack类。  显示定义析构函数 在对象声明周期结束时,程序会自动调用析构函数完成资源清理  默认生成的析构函数 1.析构函数不对内置类型做处理,因为内置类型变量的内存会随着栈帧的销毁而被回收 2.若类中存在自定义类型,则编译器会自动调用自定义类类型的析构函数 Date类中并没有显式定义析构函数。当需要销毁对象d的时候编译器会自动生成一个析构函数用于对Date类中的动态资源的清理如果有自定义类型则会去调用自定义类型自己的析构函数。 总之:创建哪个类的对象则调用该类的构造函数销毁那个类的对象则调用该类的析构函数 四:拷贝构造函数 拷贝构造函数:只有单个形参该形参是对本类类型对象的引用(一般常用const修饰)在用已存 在的类类型对象创建新对象时由编译器自动调用,用来创建一个与已存在对象一某一样的新对象 特性: 拷贝构造函数是构造函数的一个重载形式。拷贝构造函数的参数只有一个且必须是类类型对象的引用使用传值方式编译器直接报错因为会引发无穷递归调用 class Date { public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}// Date(const Date d) // 正确写法Date(const Date d) // 错误写法编译报错会引发无穷递归{_year d._year;_month d._month;_day d._day;} private:int _year;int _month;int _day; }; int main() {Date d1;Date d2(d1);return 0; } 对于值传参的函数,形参是实参的一份拷贝,在C中,这个拷贝需要调用拷贝构造函数,如果拷贝构造函数的形参没有加引用的话,就会导致无穷递归调用构造拷贝函数 3. 若未显式定义编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝这种拷贝叫做浅拷贝或者值拷贝。 ps.若类成员中存在自定义类型则会调用该类型自己的拷贝构造函数来拷贝这个类型 4.问题来了:         如果一个类没有显式定义自己的拷贝构造函数,编译器会自动生成一个拷贝构造函数,就算类中存在自定义类型,编译器也会调用该自定义类型自己的拷贝构造函数,那是不是就可以不显式定义拷贝构造函数了?看如下情景: // 这里会发现下面的程序会崩溃掉这里就需要我们以后讲的深拷贝去解决。 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; } [崩溃原因]:         创建对象d1时对d1._array动态开辟了一部分空间,而拷贝构造d2对象时,由于编译器自动生成的拷贝构造函数是按字节完成拷贝的浅拷贝,则d2._array指针指向的也是d1._array所指的空间,这样当d2对象生命周期结束时,会调用析构函数将这个空间回收,那么d1所指空间也被回收了,当d1的生命周期结束时也会调用析构函数,同一块空间被free两次就会导致程序崩溃 类中如果没有涉及资源申请时拷贝构造函数是否写都可以一旦涉及到资源申请时则拷贝构造函数是一定要写的否则就是浅拷贝。 正确写法: 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;}//拷贝构造函数Stack(const Stack d){DataType* tmp (DataType*)malloc(sizeof(DataType) * d._capacity);if (tmp nullptr){perror(malloc);return;}memcpy(tmp, d._array, sizeof(DataType) * d._size);_array tmp;_size d._size;_capacity d._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; }; 5. 拷贝构造函数典型调用场景 使用已存在对象创建新对象函数参数类型为类类型对象函数返回值类型为类类型对象 建议: 为了提高程序效率一般对象传参时尽量使用引用类型返回时根据实际场景能用引用尽量使用引用。 五:运算符重载 概念:         C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数类似。 函数名字为关键字operator后面接需要重载的运算符符号。函数原型返回值类型 operator操作符(参数列表) 返回值类型 operator 运算符(形参表) {.... } 注意 不能通过连接其他符号来创建新的操作符比如operator重载操作符必须有一个类类型参数用于内置类型的运算符其含义不能改变例如内置的整型不 能改变其含义作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this.*   ::   sizeof   ?:   . 注意以上5个运算符不能重载。 实现举例: 实现1: 将重载函数定义在全局(成员变量要定义为public,在类外才能使用) class Date { public://构造函数Date(int year 2024, int month 2, int day 2){_year year;_month month;_day day;}//注意此时成员变量是公有的int _year;int _month;int _day; }; bool operator(const Date d1,const Date d2) {return d1._year d2._year d1._month d2._day d1._day d2._day; } int main() {Date d1(2024, 8, 14);Date d2(2024, 8, 1);//调用运算符重载函数cout operator(d1,d2) endl;//简写cout (d1 d2) endl;return 0; } 实现2:将重载函数定义为成员函数 class Date { public://构造函数Date(int year 2024, int month 2, int day 2){_year year;_month month;_day day;}bool operator(const Date d){return _year d._year _month d._day _day d._day;} private:int _year;int _month;int _day; }; int main() {Date d1(2024, 8, 14);Date d2(2024, 8, 1);//调用运算符重载函数cout d1.operator(d2) endl;//简写cout (d1 d2) endl;return 0; } 六:赋值运算符重载 赋值重载的作用是将一个已经存在的对象赋值给另一个已经存在的对象(要区分拷贝构造函数) 1. 赋值运算符重载格式 虽然上述赋值重载的写法可以完成赋值的作用,但是它的功能却不完善 对于普通类型可以进行连续赋值 ijk10,但是按刚刚的写法却不能实现对象的连续赋值,要明白怎么怎么解决要先了解赋值语句的返回值: 例如:  ijk10 编译器会先把10赋值给k,然后返回k的值赋值给j,再返回j的值赋值给i,也就是赋值语句会返回左操作数 所以要想实现连续赋值我们需要将函数的返回值定义为类的类型 总结: 参数类型const T传递引用可以提高传参效率返回值类型T返回引用可以提高返回的效率有返回值目的是为了支持连续赋值检测是否自己给自己赋值返回*this 要复合连续赋值的含义 //赋值重载Date operator(const Date d){if (this ! d){_year d._year;_month d._month;_day d._day;}return *this;} 2.赋值运算符只能重载成类的成员函数不能重载成全局函数 原因赋值运算符如果不显式实现编译器会生成一个默认的。此时用户再在类外自己实现 一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了故赋值 运算符重载只能是类的成员函数 3.用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。 注意内置类型成员变量是直接赋值的而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。 重点:         如果类中未涉及到资源管理赋值运算符是否实现都可以一旦涉及到资源管理则必须要实现(与拷贝构造原理类似) 七.const成员  将 const 修饰的“成员函数”称之为 const成员函数const修饰类成员函数实际修饰该成员函数隐含的this指针表明在该成员函数中不能对类的任何成员进行修改。  const对象不可以调用非const成员函数 非const对象可以调用const成员函数 const成员函数内不可以调用其它的非const成员函数 非const成员函数内可以调用其它的const成员函数 八:取地址及const取地址操作符重载  这两个默认成员函数一般不用重新定义 编译器默认会生成 class Date {public :Date* operator(){return this ;}const Date* operator()const{return this ;}private :int _year ; // 年int _month ; // 月int _day ; // 日 };  这两个运算符一般不需要重载使用编译器生成的默认取地址的重载即可只有特殊情况才需要重载比如想让别人获取到指定的内容
http://www.w-s-a.com/news/406291/

相关文章:

  • 石岩做网站哪家好石家庄做网站设计
  • 建设网站需要冠县做网站
  • 保定网站seo哪家公司好wordpress教程视频下载
  • 网站开发 哪些文档网站海外推广方法
  • 广西建设局网站首页如何做条形码网站怎么搞
  • 琼海建设网站wordpress 商城站下载地址
  • 网站需要多大数据库divider wordpress
  • 兰州北京网站建设网络广告推广网站
  • 宁晋网站建设森网站建设
  • 网站没有收录原因trel域名
  • 建设门户网站的目的和需求台州专业网站建设方案
  • 苏州网站建设系统方案成都行业网站设计
  • wordpress多说读者墙seo分析师招聘
  • 视频网站开发计划书wordpress文件详情
  • 重庆付费网站推广电商网站 开发周期
  • thinkcmf 做企业网站视频播放类网站建设费用
  • vps网站助手大学选修课网站建设
  • 南浦电商网站建设北京海淀社保网站
  • 传奇网站模板怎么做的吗大连警方最新通告
  • 成都私人做公司网站的北京网站建设需要多少钱
  • 魔客吧是什麼程序做的网站代理厦门网站设计公司
  • 90设计手机站东营网站推广
  • 哪家购物网站建设好专门做水生植物销售网站
  • php医院网站开发兼职app开发网上app开发
  • 接任务做兼职的的网站衡阳手机网站设计
  • 徐州经济开发区网站佛山百度关键词seo外包
  • 肃宁网站建设有限责任公司法人承担什么责任
  • 珠海斗门建设局网站如何免费做网站
  • 自助外贸网站建设可直接打开网站的网页
  • 江苏城嘉建设工程有限公司网站潍坊网站定制公司