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

如何做垂直网站网站建设移动端官网

如何做垂直网站,网站建设移动端官网,数字化转型对企业的影响,跨境电商无货源模式怎么做目录 1.运算符重载 2.四种运算符重载 #xff08;1#xff09;关系运算符的重载 #xff08;2#xff09; 左移运算符的重载 #xff08;3#xff09;下标运算符的重载 #xff08;4#xff09;赋值运算符的重载 3.继承的方式 4.继承的对象模型 5.基类的构造 6…目录 1.运算符重载 2.四种运算符重载 1关系运算符的重载 2 左移运算符的重载 3下标运算符的重载 4赋值运算符的重载 3.继承的方式 4.继承的对象模型 5.基类的构造 6.名字遮蔽和类作用域 7.类继承的特殊关系 8.多态和虚函数 1.运算符重载 1其实这个知识我们并不是很陌生我们在C语言学习阶段就知道了*这个运算符在我们学习基本的运算的时候这个运算符就是用来计算乘法的但是后来我们学到了指针之后这个运算符就用来表示对于一个指针变量的解引用这个时候我们就已经认识到了一个运算符的重载功能 2我们通过下面这个实际的场景认识一下什么是c里面的运算符重载我们下面的这个代码场景是要为这个超女的分数上面加上30分这个时候如果我们直接拿这个对象和数字相加编译器是肯定不会通过的因为这个编译器不知道要把这个数据加到那个成员变量上面去 3针对这个问题我们有两种解决方案第一种就是设置一个函数实现这个加分的功能指定这个分数加到那个成员变量上面去我们原本初始化这个分数是90加上30分之后这个分数就变成了120分 #includestring using namespace std; class cgril {friend void addscore(cgril g, int score); private:int m_xw;//超女的行为int m_score;//超女的分数 public:string m_name;//超女的姓名cgril(){m_xw 60;m_name 张三;m_score 90;}void show(){cout 行为 m_xw 分数 m_score 姓名 m_name endl;} }; void addscore(cgril g, int score)//利用函数实现加分的功能 {g.m_score g.m_score score; } int main() {//导演的要求就是每轮表演之后加上对应的得分cgril g;addscore(g, 30);g.show();return 0; } 4上面的这个写法偏向于C的写法接下来我们看一下如何使用C写法实现这个加分的功能就是把这个函数的名字修改为operator即可这个operator是关键字就是我们想要重载的运算符  5上面的这个运算符重载的基本写法实际上这个运算符的重载既可以写作成员函数也可以写作全局函数当我们实现一个类和一个整形数据加法的时候如果我们写在成员函数里面就可以只写一个参数最后的返回值是*this,这个时候写法是这样的 cgril operator(int score)//利用函数实现加分的功能{m_score m_score score;return *this;} }; int main() {//导演的要求就是每轮表演之后加上对应的得分cgril g;g g 30;g.show();return 0; } 这个时候那个对象调用这个成员函数那个对象就是this指针这样写在成员函数里面我们就不需要写这个友元函数了因为这个在类的里面我们是可以对于这个私有的成员变量直接进行使用这个时候gg30我们需要把这个返回值设置为这个类的引用类型 6当这个函数写在全局里面时候有几个操作数我们就需要写几个操作数而且这个操作数的数据类型和我们使用的数据类型之间应该是一一对应的例如我们想要实现这个cgrilint我们在使用这个加法运算符的时候我们就必须把这个类写在左边int类型的数据写在右边这个顺序是不可以改变的 7下面的这些运算符重载的时候必须写在这个成员函数里面去赋值运算符    函数调用运算符    下标运算符[  ]      以及这个指针访问成员操作符-    2.四种运算符重载 1关系运算符的重载 关系运算符就是我们常说的这个大于小于和等于这些符号的比较我们对于两个类之间的比较需要自己进行运算符的重载 下面的就是重载了等于号大于号和小于号的运算符重载代码 class student {string m_name;int m_cj;//学生成绩int m_bx;//学生的表现int m_td;//学生的学习态度 public:student(string name, int cj, int bx, int td){m_name name;m_cj cj;m_bx bx;m_td td;}bool operator(const student s){if (m_cj m_bx m_td s.m_cj s.m_bx s.m_td){return true;}else{return false;}}bool operator(const student s){if (m_cj m_bx m_td s.m_cj s.m_bx s.m_td){return true;}else{return false;}}bool operator(const student s){if (m_cj m_bx m_td s.m_cj s.m_bx s.m_td){return true;}else{return false;}} }; int main() {student s1(张三, 80, 20, 70);student s2(李四, 70, 70, 30);if (s1 s2){cout 张三和李四的分数一样 endl;}else{if (s1 s2){cout 张三比李四的分数低 endl;}else{cout 张三比李四的分数高 endl;}}return 0; } 2 左移运算符的重载 这个cout有15种重载因此可以输出各种数据类型的数据但是cout无法输出我们自己定义的类和对象这个时候就需要我们对于其进行重载cout这个对象的返回值实际上就是一个ostream类型的这个如果是全局函数就需要两个参数一个就是cout对象一个就是我们的自定义类型的对象如果是成员函数的话就只需要一个参数因为对象本身是隐式传递的不能出现在形参列表里面 using namespace std; class student {friend ostream operator(ostream cout, const student s);int m_mark;string m_name; public:student(){m_mark 90;m_name 张三;}void show(){cout 这个同学的姓名是 m_name 成绩是 m_mark endl;} }; ostream operator(ostream cout, const student s) {cout 姓名 s.m_name 分数 s.m_mark endl;return cout; } int main() {student s1;cout s1 endl;return 0; } 成员函数版本的运算符重载 #includestring using namespace std; class student {//friend ostream operator(ostream cout, const student s);int m_mark;string m_name; public:student(){m_mark 90;m_name 张三;}void show(){cout 这个同学的姓名是 m_name 成绩是 m_mark endl;}ostream operator(ostream cout){cout 姓名 this-m_name 分数 this-m_mark endl;return cout;} }; int main() {student s1;s1 cout endl;return 0; } 我们可以理解为这个运算符左右两边一共有两个操作数这个时候我们的自定义类型作为一个隐藏的参数所以对应的主函数里面这个自定义对象和cout对象的位置需要被改变 这个时候cout在右边不是我们想要的结果因此这个左移运算符的重载只能写成这个全局函数不能写成成员函数 3下标运算符的重载 如果没有重载下标运算符如果我们想要查看这个数组元素我们就需要自己定义函数使用这个小括号加上下标的方式表示但是我们知道这个访问操作符就是中括号因此下面我们介绍小标访问运算符的重载 #includeiostream #includestring using namespace std; class student { private:string m_zy[3]; public:student(){m_zy[0] 父母;m_zy[1] 老师;m_zy[2] 朋友;}void show(){cout m_zy[0] m_zy[1] m_zy[2] endl;}string operator[](int ii){return m_zy[ii];} }; int main() {student s1;s1[2] 知己;cout 第三亲密 s1[2] endl;s1.show();return 0; } 实际在开发的过程中我们需要有两个版本的重载函数一个版本是可以对于我们的数据进行修改的另外的一个就是针对常变量只能调用常函数 #includeiostream #includestring using namespace std; class student { private:string m_zy[3]; public:student(){m_zy[0] 父母;m_zy[1] 老师;m_zy[2] 朋友;}void show(){cout m_zy[0] m_zy[1] m_zy[2] endl;}string operator[](int ii){return m_zy[ii];}const string operator[](int ii) const{return m_zy[ii];} }; int main() {student s1;s1[2] 知己;cout 第三亲密 s1[2] endl;s1.show();const student s2 s1;cout 第三亲密 s2[2] endl;return 0; } 4赋值运算符的重载 赋值运算符其实编译器会提供默认的我们了解即可这个我们在重载赋值运算符的时候需要判断这个时不时会出现自己给自己赋值的情况这个是合法的我们直接返回this解引用即可this就是我们想要赋值的对象 编译器默认提供的赋值构造函数是浅拷贝如果这个不存在动态开辟空间就可以满足需求否则的话就需要我们自己实现深拷贝 #includeiostream #includestring using namespace std; class student { public:string m_name;int m_score;void show(){cout 姓名 m_name 年龄 m_score endl;}student operator(const student s){if (this s)return *this;else{m_name s.m_name;m_score s.m_score;}return *this;} }; int main() {student s1;s1.m_name 张三;s1.m_score 100;s1.show();student s2;s2 s1;s2.show();return 0; } 3.继承的方式 1三种不同的继承方式 上面展示的就是三种不同的继承方式我们假设这个基类有三个成员变量一个是共有的一个是受保护的一个是私有的经过不同的继承方式之后这个成员变量的类型会发生什么变化 第一种就是公有继承公有继承的时候我们的父类里面的公有成员还是公有成员受保护的成员还是受保护的成员私有成员就不存在了 第二种是受保护的继承这个时候原来的公有成员就变成了受保护的成员原来的父类里面的受保护的成员还是受保护的原来的私有成员变量这个时候还是不存在的 第三种就是私有的继承这个时候原来的父类里面的共有的成员变量和保护的成员变量就是私有的了原来的父类里面的受保护的成员变量也是不存在的 2我们在这个继承的子类里面是没有办法访问这个所谓的父类里面的私有成员变量的但是如果我们想要在这个子类里面去访问这个私有的成员变量可以在父类里面添加共有的函数访问这个私有的成员变量这个时候我们就可以直接调用这个函数访问父类里面的私有的成员变量 就像下面的展示那样我们在子类里面本来是没有办法去访问父类的私有成员变量的但是我们可以在父类里面创建共有的成员函数这样在子类里面我们就可以通过调用这个函数达到间接访问了父类的私有成员变量的目的 class comers { private:int m_aa; public:void func(){cout m_aa endl;} }; class comerss :public comers { private:int m_bb; public:void show(){func();} }; int main() {comerss c1;c1.show();return 0; } 3我们可以使用using 关键字改变父类的成员变量的访问权限例如我们可以把这个共有的改变成为受保护的把这个受保护的改变权限为共有的这个父类里面的私有的成员变量的权限是没有办法通过这个关键字改变的因为这个父类里面的私有的成员变量在这个子类里面根本就不会存在因此这个关键字只对于public权限和protected权限发挥作用 class a { public:int m_a; protected:int m_b; private:int m_c; }; class b :public a { public:using a::m_b; protected:using a::m_a; }; int main() { b bb1;return 0; } 通过上面的这个具体的实例我们就可以把这个父类里面的公有成员变量修改为受保护的把这个受保护的成员变量修改权限为公有的当然也可以把他们的权限设置为私有的 4.继承的对象模型 1这个地方是帮助我们了解C继承语法的底层逻辑而不是学懂这个底层逻辑我们只是了解这样就可以让我们更好理解前面的一些原因 2第一点就是基类在写这个构造函数的时候会先运行这个父类的构造函数再去运行这个基类的构造函数这个我们可以进行尝试当我们创建两个类假设是A类和B类如果A是父类B是子类我们把这个A类里面的构造函数设置为私有的这个时候我们在B这个子类里面去写构造函数就会报错原因就是我们上面提及到的我们在执行子类的构造函数的时候会先执行父类的构造函数这个也是为什么我们建议把这个函数写为共有的成员变量写为私有的这个时候我们学习了继承就可以更好地进行理解 3销毁子类对象的时候会先执行子类的析构函数再去执行父类的析构函数这个和构造函数的执行顺序是恰好相反的 4创建派生类对象的时候只申请了一次这个内存申请的内存空间的大小就是基类加上派生类的内存的和先调用基类的构造函数初始化基类再调用派生类的构造函数初始化派生类在基类和派生类的构造函数里面this指针是相同的地址派生类和基类都有的成员变量的地址也是一样的 5在C里面这个成员变量的访问权限只是语法上面的限制我们可以使用memset函数清零数据包括这个私有的成员变量即使这个私有的成员变量在类的外面不能被访问我们可以使用指针突破这个访问权限的限制所以这个访问权限只是语法上面的一个解释罢了 5.基类的构造 1我们可以使用初始化列表的方式指定要使用的基类的构造函数类型因为我们前面提及过这个创建子类也就是派生类的对象的时候需要先去调用这个父类的构造函数这个时候如果父类里面有多个构造函数我们就可以使用初始化列表的方式指定调用基类里面的哪个构造函数 2我们在创建派生类的对象的时候是使用基类初始化这个基类的成员变量派生类初始化派生类的成员变量你可能会问这些基类的成员变量都被派生类给继承了为什么不使用派生类初始化基类的成员变量这个有两点原因 第一就是我们的基类里面的私有的成员变量我们是无法在这个派生类里面看到的更别说去对于这个变量进行初始化了 第二就是这个如果我们在这个派生类里面对于这个基类的成员变量进行初始化如果这个基类有很多个派生类我们的这个代码就显得很冗余而且这个派生类存在的意义就是减少这个相同的成员变量的书写带来的麻烦这样搞得话就不符合这个逻辑了 3下面的就是我们定义了一个派生类和一个基类通过初始化列表的方式确定这个派生类调用的是基类里面的哪个构造函数 class a { public:int m_a; private:int m_b; public:a():m_a(0), m_b(0){cout 调用了基类的构造函数 endl;}a(int aa, int bb):m_a(aa), m_b(bb){cout 调用了含有两个参数的构造函数 endl;}a(const a aa):m_a(aa.m_a 1), m_b(aa.m_b 1){cout 调用了基类的拷贝构造函数 endl;}void showa(){cout m_a数值大小 m_a m_b的数值大小 m_b endl;} }; class b :public a { public:int m_c;b():m_c(0),a(){cout 调用了这个派生类的构造函数 endl;}b(int a, int b, int c):a(a, b), m_c(c){cout 调用派生类的构造函数b(int a, int b, int c) endl;}b(const a aa, int c):a(aa), m_c(c){cout 调用派生类的拷贝构造函数 endl;}void showb(){cout m_c数值大小 m_c endl;} }; int main() {b b1;b1.showa();b1.showb();cout endl;b b2(1, 2, 3);b2.showa();b2.showb();cout endl;a a1(10, 20);b b11(a1, 30);return 0; } 我们分别使用初始化列表的方式指定了调用默认的构造函数调用含有多个参数的构造函数以及这个拷贝构造函数子类里面的第二个初始化列表我们使用的是这个基类的含有两个参数的构造函数进行初始化的第三个初始化列表是使用基类里面的拷贝构造函数进行初始化的 6.名字遮蔽和类作用域 1下面就是定义了一个基类和一个子类我们创建了一个子类的对象这个基类和子类的这个成员变量的名字以及这个成员函数的名字都是一样的这个时候我们的打印结果就是基类的成员变量和成员函数 using namespace std; class a { public:int m_a 20;void show(){cout 调用了基类的函数 endl;} }; class b :public a { public:int m_a 30;void show(){cout 调用了派生类的函数 endl;} }; int main() {b b1;cout b1对象的m_a的值是 b1.m_a endl;b1.show();return 0; } 2当基类的函数名和这个派生类里面的函数名字相同的时候因为这个是继承所以派生类里面就会隐含的包括了这个基类的成员变量和成员函数名字相同的时候派生类的函数就会把这个基类里面函数覆盖掉 using namespace std; class a { public:int m_a 20;void show(){cout 调用了基类的函数 endl;}void func(int a){cout 调用了这个函数 endl;} }; class b :public a { public:int m_a 30;//void func() { cout 调用了派生类的函数 endl; } }; int main() {b b1;cout b1对象的m_a的值是 b1.m_a endl;b1.show();b1.func(1); } 例如上面的这个程序两个相同的函数func如果我们把这个继承类里面的func函数放开这个时候运行就会报错因为这个时候父类的func函数会被覆盖掉我们传递参数是不合语法的但是我们把这个注释掉之后就可以运行成功因为这个时候不存在函数名字相同的情况我们就可以直接调用这个子类里面的有一个参数的func函数了实际上这个成员函数在子类里面也是存在的只要不重名这个基类里面的这个函数就不会被覆盖掉 实际上这个名字遮蔽就是一个表象类作用域才是实质因为实际上当存在继承关系的时候这个基类的作用域是嵌套在这个派生类里面的我们一般会在这个派生类里面去寻找只有这个在派生类里面找不到的时候才回到基类里面去寻找 7.类继承的特殊关系 1如果我们使用派生类的对象赋值给基类的对象包括私有成员但是这个时候会舍弃掉非基类成员 下面这个代码里面我们对于这个b1对象进行操作最后把他赋值给a1这个对象这个时候我们会发现a1这个对象里面的私有成员m_b也会被更新的也就是说即使是私有的成员变量也是会被赋值的 class a { public:int m_a 0; private:int m_b 0; public:void show(){cout m_a: m_a m_b: m_b endl;}void setb(int b){m_b b;} }; class b :public a { public:int m_c 0;void show(){cout m_a: m_a m_c: m_c endl;} }; int main() {a a1;b b1;b1.m_a 10;b1.setb(20);b1.m_c 30;a1.show();a1 b1;a1.show();return 0; } 2基类的指针可以不经过显示转换指向派生类的对象因为基类和派生类有特殊的关系他们的内存模型是一样的所以使用基类的指针执行派生类没有问题 还是上面得继承关系我们定义基类的指针指向派生类的对象 int main() {b b1;a* a1 b1;b1.m_a 10;b1.setb(20);b1.m_c 30;b1.show();a1-m_a 10;a1-setb(20);a1-show();return 0; } 8.多态和虚函数 1什么是多态 多态就是我们定义了两个类之间的继承关系定义了基类的指针pa,指向的是派生类的对象g,这个时候我们使用这个指针去调用函数就只能调用基类的构造函数因为这个指针就是基类的 我们在这个基类的成员函数show前面加上virtual关键字就可以使用这个执行派生类对象的指针去访问这个派生类的函数即使这个类是基类的我们也是可以访问到这个派生类的成员函数的 因为这个是函数前面加上virtual关键字我们把这个函数叫做虚函数有了虚函数之后基类的指针指向基类对象就会调用基类的成员变量和函数指向派生类的对象之后就会调用派生类的成员变量和函数基类的指针表现出来多种形态我们把这个现象叫做多态 class allcomer { public:int m_bh;void show(){cout class allcomer我的编号是 m_bh endl;} }; class cgril :public allcomer { public:int m_age;void show(){cout class cgril :public allcomer我的年龄是 m_age endl;} }; int main() {cgril g;g.m_bh 8;g.m_age 18;g.show();allcomer* pa g;pa-show();return 0; }
http://www.dnsts.com.cn/news/222722.html

相关文章:

  • 茂名市城乡和住房建设局网站遵义网络推广软文
  • 云平台网站建设钉钉付费版多少钱
  • 现在找个网站这么难的吗胶州专业建站
  • 网站公司怎么做的网站被k是怎么回事
  • 潍坊公司做网站seo网络排名优化技巧
  • 做网站专用软件wordpress主页与文章页
  • dedecms手机网站国家工商网查询企业信息
  • 江阴建设局网站网站建设满意度调查问卷
  • 南通网站建设系统成都手机网站设计
  • 佛山高端网站制作公司网站的盈利方法
  • wordpress的页面链接错乱seo优化方案
  • 宣传网站制作方案wordpress怎么调用默认的分页代码
  • 成都科技网站建设wifi和卫星有关系吗
  • 长沙一站式网站建设网站开发合同模板免费
  • wordpress首部如何添加自定义代码廊坊seo外包公司费用
  • 网站建设价目表上海某家具网站建设方案
  • 网站推广的具体内容在线做免费网站有哪些
  • 合肥网站关键词优化二七郑州网站建设
  • 淮北网站三合一建设公司营销号视频生成器网页版
  • 化妆品网站建设思路新手做网页做那个网站简单
  • 写作网站哪个好用网站建设合同违约金一般多少
  • 杭州便宜的手机网站建设查域名注册信息
  • 互联网公司岗位有哪些企业网站怎么做seo
  • 品牌网站设计打造适应移动端网站模板
  • 个人备案可以做盈利网站吗全国生猪价格
  • 幸运飞艇网站建设建设网站报价
  • 贷款网站平台有哪些模板网站的劣势
  • 网站设计好网站做网站实训目的和意义
  • 好的网站建设一般网站建设公司好
  • 朝阳免费网站制作网站建设佰首选金手指二八