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

建站平台在线提交表格天津网站经营性备案

建站平台在线提交表格,天津网站经营性备案,北京未来广告公司,自己有服务器怎么建设网站目录 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 2. 赋值运算符只能重载成类的成员函数不能重载成全局函数 3. 用户没有显式实现时…目录 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 2. 赋值运算符只能重载成类的成员函数不能重载成全局函数 3. 用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。注 意内置类型成员变量是直接赋值的而自定义类型成员变量需要调用对应类的赋值运算符 重载完成赋值。 1.类的6个默认成员函数 如果一个类中什么成员都没有简称为空类。 空类中真的什么都没有吗并不是任何类在什么都不写时编译器会自动生成以下6个默认成员函数。 默认成员函数用户没有显式实现编译器会生成的成员函数称为默认成员函数。 意思就是我们在类里不写函数编译器也会为我们生成默认函数是无参的   class Date {};2. 构造函数 2.1 概念 对于以下Date类 class Date { public:void Init(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.Init(2022, 7, 5);d1.Print();Date d2;d2.Init(2022, 7, 6);d2.Print();return 0; } 用Init初始化容易忘记初始化定义后直接push 对于Date类可以通过 Init 公有方法给对象设置日期但如果每次创建对象时都调用该方法设置信息未免有点麻烦那能否在对象创建时就将信息设置进去呢 构造函数是一个特殊的成员函数名字与类名相同,创建类类型对象时由编译器自动调用以保证每个数据成员都有一个合适的初始值并且在对象整个生命周期内只调用一次。 2.2 特性 对象定义(实例化)的时候一定要调用构造函数 构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。 他是一个特殊的成员函数不能以普通函数来对待他所以比较复杂。 其特征如下 1. 函数名与类名相同。 2. 无返回值。(不是void,而是就不需要写而且void是空返回值) 3. 对象实例化时编译器自动调用对应的构造函数。 4. 构造函数可以重载。 #includeiostream using namespace std; class Date { public:Date()//无参构造进行初始化{_year 1900;_month 1;_day 1;}void print() {cout _year endl;cout _month endl;cout _day endl;} private:int _year;int _month;int _day; }; int main() {Date d1;d1.print();return 0; }   class Date { public:// 1.无参构造函数//Date()//{// _year 1900;// _month 1;// _day 1;//}// 2.带参构造函数Date(int year1, int month1, int day1)//还可以构成函数缺省{_year year;_month month;_day day;}//两个Date形成函数重载,语法上这两个函数都可以存在但是实际上会出问题“Date::Date”: 对重载数数的调用不明确 //但同时可以发现缺省构造函数可以覆盖无参构造只有加了缺省才能使用Date d1;d1.print();否则会报错void print() {cout _year endl;cout _month endl;cout _day endl;} private:int _year;int _month;int _day; };int main() {Date d1; // 调用无参构造函数Date d2(2015, 1, 1); // 调用带参的构造函数Date d2(2015); // 调用带参的构造函数且是函数缺省// 注意如果通过无参构造函数创建对象时对象后面不用跟括号否则就成了函数声明// 以下代码的函数声明了d3函数该函数无参返回一个日期类型的对象// warning C4930: “Date d3(void)”: 未调用原型函数(是否是有意用变量定义的?)//Date d3();//不能这样写因为这样可能会与函数声明混淆date为返回类型d3()为声明d1.print();d2.print();d3.print();return 0; } Date d1; 是创建对象并调用默认构造函数初始化而 Date d2(); 则是声明一个函数而不是创建对象 5. 如果类中没有显式定义构造函数则C编译器会自动生成一个无参的默认构造函数一旦用户显式定义编译器将不再生成。 我们开始调用系统默认的构造函数但是它不发挥作用打印随机值 #includeiostream using namespace std; class A { public:A() {_a 0;cout _a endl;cout _a endl;} private:int _a; }; class Date { public:void Print(){cout _year _month _day endl;} private:int _year1;int _month2;int _day;A _aa; };int main() {Date d1;d1.Print();return 0; } C把数据分为内置类型/基本类型  和自定义类型 内置类型/基本类型:int/char/double/各种指针   语法自身定义的类型 自定义类型:struct/class  也就是更复杂的类型自己根据需求写的 默认生成的构造函数对于内置类型不做处理对于自定义类型调用他的默认构造 C11委员会对语法进行补充可以在声明的时候给缺省值需要注意的是成员变量虽然被附上了值但这里仍然是一个声明且不开辟空间 C11之前不支持 6. 关于编译器生成的默认成员函数很多童鞋会有疑惑不实现构造函数的情况下编译器会 生成默认的构造函数。但是看起来默认构造函数又没什么用d对象调用了编译器生成的默 认构造函数但是d对象_year/_month/_day依旧是随机值。也就说在这里编译器生成的 默认构造函数并没有什么用 解答C把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类 型如int/char...自定义类型就是我们使用class/struct/union等自己定义的类型看看 下面的程序就会发现编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员 函数。 class Time { public:Time(){cout Time() endl;_hour 0;_minute 0;_second 0;} private:int _hour;int _minute;int _second; }; class Date { private:// 基本类型(内置类型)int _year;int _month;int _day;// 自定义类型Time _t; }; int main() {Date d;return 0; } 注意C11 中针对内置类型成员不初始化的缺陷又打了补丁即内置类型成员变量在 类中声明时可以给默认值。 class Time { public:Time(){cout Time() endl;_hour 0;_minute 0;_second 0;} private:int _hour;int _minute;int _second; }; class Date { private:// 基本类型(内置类型)int _year 1970;int _month 1;int _day 1;// 自定义类型Time _t; }; int main() {Date d;return 0; } 7. 无参的构造函数和全缺省的构造函数都称为默认构造函数并且默认构造函数只能有一个。 注意无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数都可以认为是默认构造函数。 class Date { public:Date(){_year 1900;_month 1;_day 1;}Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;} private:int _year;int _month;int _day; }; // 以下测试函数能通过编译吗 void Test() {Date d1; } 不能通过编译只能有一个 结论分析一个类型成员和初始化需求需要写构造函数我们就自己写不需要时就编译器自己生成。但是绝大部分场景下都需要自己实现构造函数只要自己构造函数了那么编译器就不会自己生成。 一般情况下建议全缺省 3.析构函数 3.1 概念 通过前面构造函数的学习我们知道一个对象是怎么来的那一个对象又是怎么没呢的 析构函数与构造函数功能相反析构函数不是完成对对象本身的销毁局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数完成对象中资源的清理工作。--即所写的内容清空 3.2 特性 析构函数是特殊的成员函数其特征如下 1. 析构函数名是在类名前加上字符 ~。 2. 无参数无返回值类型。 3. 一个类只能有一个析构函数。若未显式定义系统会自动生成默认的析构函数。注意析构函数不能重载 4. 对象生命周期结束时C编译系统系统自动调用析构函数。 #includeiostream using namespace std; typedef int DataType; class Stack { public:Stack(size_t capacity 3){_array (DataType*)malloc(sizeof(DataType) * capacity);if (NULL _array){perror(malloc申请空间失败!!!);return;}_capacity capacity;_size 0;}void Push(DataType data){// CheckCapacity();_array[_size] data;_size;}// 其他方法...~Stack(){if (_array){free(_array);_array NULL;_capacity 0;_size 0;}} private:DataType* _array;int _capacity;int _size; }; int main() {Stack s;s.Push(1);s.Push(2);return 0; } 局部变量在函数调用时会被分配在栈内存上并且它们遵循后进先出的原则。根据生命作用域进行析构 析构顺序 局部变量(后定义先析构)-局部静态变量(等局部析构完后再后定义先析构)-全局变量(不分静态是否都是后定义先析构) 局部变量后定义先销毁静态变量最后销毁s3虽然是局部的但是生命周期是全局的因为他在静态区 5. 关于编译器自动生成的析构函数是否会完成一些事情呢下面的程序我们会看到编译器生成的默认析构函数对自定类型成员调用它的析构函数。 #includeiostream using namespace std; class Time { public:~Time(){cout ~Time() endl;} private:int _hour;int _minute;int _second; }; class Date { private:// 基本类型(内置类型)int _year 1970;int _month 1;int _day 1;// 自定义类型Time _t; }; int main() {Date d;return 0; } 程序运行结束后输出~Time()  在main方法中根本没有直接创建Time类的对象为什么最后会调用Time类的析构函数  因为main方法中创建了Date对象d而d中包含4个成员变量其中_year, _month, _day三个是内置类型成员销毁时不需要资源清理最后系统直接将其内存回收即可而_t是Time类对象所以在d销毁时要将其内部包含的Time类的_t对象销毁所以要调用Time类的析构函数。但是 main函数中不能直接调用Time类的析构函数实际要释放的是Date类对象所以编译器会调用Date 类的析构函数而Date没有显式提供则编译器会给Date类生成一个默认的析构函数目的是在其内部调用Time类的析构函数即当Date对象销毁时要保证其内部每个自定义对象都可以正确销毁main函数中并没有直接调用Time类析构函数而是显式调用编译器为Date类生成的默认析 构函数 注意创建哪个类的对象则调用该类的析构函数销毁那个类的对象则调用该类的析构函数 6. 如果类中没有申请资源时析构函数可以不写直接使用编译器生成的默认析构函数比如 Date类有资源申请时一定要写否则会造成资源泄漏比如Stack类。 4. 拷贝构造函数 4.1 概念 在现实生活中可能存在一个与你一样的自己我们称其为双胞胎。 那在创建对象时可否创建一个与已存在对象一某一样的新对象呢 拷贝构造函数只有单个形参该形参是对本类类型对象的引用(一般常用const修饰)在用已存 在的类类型对象创建新对象时由编译器自动调用。 4.2 特征 拷贝构造函数也是特殊的成员函数其特征如下 1. 拷贝构造函数是构造函数的一个重载形式。 2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用使用传值方式编译器直接报错 因为会引发无穷递归调用。 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; }3. 若未显式定义编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按 字节序完成拷贝这种拷贝叫做浅拷贝或者值拷贝。 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 { private:// 基本类型(内置类型)int _year 1970;int _month 1;int _day 1;// 自定义类型Time _t; }; int main() {Date d1;// 用已经存在的d1拷贝构造d2此处会调用Date类的拷贝构造函数// 但Date类并没有显式定义拷贝构造函数则编译器会给Date类生成一个默认的拷贝构 造函数Date d2(d1);return 0; } 注意在编译器生成的默认拷贝构造函数中内置类型是按照字节方式直接拷贝的而自定 义类型是调用其拷贝构造函数完成拷贝的。 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; } 5. 拷贝构造函数典型调用场景 使用已存在对象创建新对象 函数参数类型为类类型对象 函数返回值类型为类类型对象 class Date { public:Date(int year, int minute, 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; }5.赋值运算符重载 5.1 运算符重载 C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其 返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数类似 函数名字为关键字operator后面接需要重载的运算符符号。 函数原型返回值类型 operator操作符(参数列表) 注意 不能通过连接其他符号来创建新的操作符比如operator 重载操作符必须有一个类类型参数 用于内置类型的运算符其含义不能改变例如内置的整型不 能改变其含义 作为类成员函数重载时其形参看起来比操作数数目少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; }; 5.2 赋值运算符重载 赋值运算符重载格式: 参数类型const T传递引用可以提高传参效率 返回值类型T返回引用可以提高返回的效率有返回值目的是为了支持连续赋值 检测是否自己给自己赋值 返回*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 ; };2. 赋值运算符只能重载成类的成员函数不能重载成全局函数 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 ”必须是非静态成员 原因赋值运算符如果不显式实现编译器会生成一个默认的。此时用户再在类外自己实现 一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了故赋值 运算符重载只能是类的成员函数。 3. 用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。注 意内置类型成员变量是直接赋值的而自定义类型成员变量需要调用对应类的赋值运算符 重载完成赋值。 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;s2 s1;return 0; } 注意如果类中未涉及到资源管理赋值运算符是否实现都可以一旦涉及到资源管理则必 须要实现。
http://www.dnsts.com.cn/news/203570.html

相关文章:

  • 做电影网站解析wordpress添加文档
  • 网站内如何做论坛东莞望牛墩网站建设
  • 丹徒网站建设机构企业电子商务网站有哪些功能
  • 九讯鹿网站建设海南seo
  • 怎么设置网站默认首页企业网站建设基本流程图
  • 咖啡网站模板html个人网站怎么制作成图片
  • 怎样提高网站访问速度石排镇做网站
  • 怎么样用自己电脑做网站html手机版下载
  • 柳州网站建设11天津网站建设价格多少
  • 网站服务器组建wordpress 邀请码注册衔接
  • 中国交建招标平台优化网络的软件
  • 淄博网站建设hidddwordpress 模版 psd
  • 网站开发设计需要什么证书国内最大的网页模板网站
  • 手机网站用户体验网站建设服务流程
  • 长春 网站 设计上海人才网站官网入口
  • 帝国cms网站地图生成器企业管理咨询服务公司
  • 容桂网站制作价位怎么制作网站视频教程
  • 类似京东的购物网站开发价格wordpress减肥网站采集规则
  • 怎么用网站做类似微博国内做网站哪家公司好
  • 网站推广意义不改变网站怎么做关键词优化
  • app网站开发的特点wordpress中文主题站
  • 重庆可视化网站制作网站关键词热度
  • 深圳学校网站建设个人创业做网站
  • 上传PDF到wordpress网站贵州省建设厅官方网站官网
  • 汽车网站制作淘客免费交易网站建设
  • wordpress电影网站模板wordpress 颜色选择器
  • 电子网站大全盘锦网站建设价位
  • 网站建设开票开什么内容微信电商平台
  • 开县集团网站建设网站建设存在的问题及建议
  • 在线编写html网页代码站内优化包括哪些