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

wordpress火车头发布接口深圳优化网站

wordpress火车头发布接口,深圳优化网站,wordpress影视主题,商城网站建设目标【C】—— 类与对象#xff08;五#xff09; 1、类型转换1.1、类型转换介绍1.2、类型转换的应用1.3、explicit 关键字 2、static 静态成员2.1、static 静态成员变量2.2、static 静态成员函数2.3、总结 3、友元3.1、友元函数3.2、友元类 4.内部类5、匿名对象6、对象拷贝时的编… 【C】—— 类与对象五 1、类型转换1.1、类型转换介绍1.2、类型转换的应用1.3、explicit 关键字 2、static 静态成员2.1、static 静态成员变量2.2、static 静态成员函数2.3、总结 3、友元3.1、友元函数3.2、友元类 4.内部类5、匿名对象6、对象拷贝时的编译器优化6.1、情况一类型转换6.2、情况二传值传参6.3、情况三传值返回 1、类型转换 1.1、类型转换介绍 我们知道整型和浮点型之间可以发生隐式类型转换 int main() {int a 2.2;cout a endl;return 0; }运行结果 int a 2.2;这句代码会发生隐式类型转换。中间生成一个临时对象将右操作数强制类型转换为左操作数的类型再将临时对象的值赋值给 a a a。    那么下面代码小伙伴们见过吗 class A { public :A(int a1): _a1(a1){}A(int a1, int a2):_a1(a1), _a2(a2){}void Print(){cout _a1 _a2 endl;} private:int _a1 1;int _a2 2; };int main() {A aa1(5);aa1.Print();A aa2 10;aa2.Print();return 0; }运行结果 诶是不是感觉怪怪的   A aa1(5);很好理解就是调用构造函数。那A aa2 10;又该怎么理解呢是拷贝构造吗如果是拷贝构造那不应该用同类的对象来初始化吗怎么现在是一个整型呢 A aa2 10;本质是一个类型转换10 从一个整型转换成了 A 类其用 10 去 构造 了一个临时对象 A类再通过拷贝构造初始化 a a 2 aa2 aa2 不过编译器会对上述过程进行优化优化为直接构造。虽然语法意义上面是走上述步骤。    int main() {A aa1(5);aa1.Print();A aa1 10;return 0; }这样引用行不行呢   不行的因为类型转换会产生一个临时对象临时对象是常性。   用 c o n s t const const 引用const A aa1 10;就可以啦      那多参数的可以吗   可以的C11 后支持了多参数的类型转换    调用方法如下 int main() {A aa1 { 3,3 };aa1.Print();return 0; }1.2、类型转换的应用 class Stack { public:void Push(const A aa){//···} private:A _arr[10];int _top; };现在我们有一个栈栈放着 A类 成员怎么插入数据呢 正常来讲是这样写 int main() {Stack st;A aa1(1);st.Push(aa1);A aa2(22);st.Push(aa2);return 0; }有了类型转换后我们就可以这样 int main() {Stack st;st.Push(1);st.Push({2,2});return 0; }效果是一样的但代码简洁了许多 这里 1 和 2.2 会构建一个临时对象再将临时对象 P u s h Push Push 这里也体现了加引用尽量加 c o n s t const const 的重要性。因为临时对象具有常性不加 c o n s t const const 会造成权限放大编译无法通过。       1.3、explicit 关键字 如果我们不想让它发生类型转换可以增加 e x p l i c i t explicit explicit 关键字 class A { public :explicit A(int a1): _a1(a1){}explicit A(int a1, int a2):_a1(a1), _a2(a2){}void Print(){cout _a1 _a2 endl;} private:int _a1 1;int _a2 2; };2、static 静态成员 2.1、static 静态成员变量 用 s t a t i c static static 修饰的成员变量称之为静态成员变量静态成员变量一定要在类外进行初始化静态成员变量为所有当前类对象所共享不属于某个具体的对象不存在对象中存放在静态区 class A { public :A(){_scount;} A(const A t){_scount;} ~A(){--_scount;} //private:// 类⾥⾯声明static int _scount;// 声明时可以给缺省值吗//static int _scount 0; };//在类外初始化 int A::_scount 0;int main() {//指定类域就可以访问_scount(公有情况下//因为_scount并不在某个对象中//cout A::_scount endl;cout sizeof(A) endl;return 0; }运行结果 上述代码中static int _scount;就是在类中定义了一个静态成员变量。 int A::_scount 1;是 _ s c o u n t scount scount 的声明静态成员变量 一定要在类外声明 静态成员变量可以认为是全局变量放在静态区并不是存在类中通过 s i z e o f sizeof sizeof 也可看出只是受类域的限制受访问限定符限制   静态成员变量 在 m a i n main main函数 之前就开辟好了并不随对象一起开辟   可以通过直接指定类域区访问静态成员变量类名::静态成员因为它不是在某个对象中公有情况下 那在类中声明时可以给缺省值吗   不可以因为声明时的缺省值是给初始化列表用的静态成员变量不是存在类里面的不走初始化列表。 2.2、static 静态成员函数 用 s t a t i c static static 修饰的成员函数称之为静态成员函数静态成员函数没有 t h i s this this指针静态成员函数可以访问其他静态成员但是不能访问非静态的因为没有 t h i s this this指针非静态的成员函数可以访问任意的静态成员变量和静态成员函数 class A { public :A(){_scount;} A(const A t){_scount;} ~A(){--_scount;} //静态成员函数static int GetACount(){return _scount;}private:// 类⾥⾯声明static int _scount; };当静态成员变量是私有就无法直接突破类域访问这时就可以使用静态成员函数来访问。   静态成员函数没有 t h i s this this指针因此只能访问静态成员变量。   静态成员函数同样可以通过通过 类名::静态函数 访问当然也可以像普通成员函数那样通过 对象.函数 来访问 int A::_scount 1; int main() {cout A::GetACount() endl;A a1, a2;A a3(a1);cout A::GetACount() endl;cout a1.GetACount() endl;return 0; }运行结果 int main() {cout A::GetACount() endl;A a1, a2;{A a3(a1);cout A::GetACount() endl;}cout a1.GetACount() endl;return 0; }运行结果 上述代码利用静态成员变量来计算该对象实例化出多少个对象。 注在 C 中任意一个 { } 中的内容都单独形成一个域。 a 3 a3 a3 是在域中创建出了作用域就销毁 同时静态成员函数只能访问静态成员变量因为静态成员函数没有 t h i s this this 指针 static int GetACount(){_a;return _scount;}但是非静态成员函数可以随便访问静态成员变量和静态成员函数因为突破类域就可以访问静态成员而非静态成员函数本来就在域中。 2.3、总结 用 s t a t i c static static 修饰的成员变量称之为静态成员变量静态成员变量一定要在类外初始化静态成员是为所有类对象所共享不属于某个具体的对象不存在对象中存放在静态区用 s t a t i c static static 修饰的成员函数称之为静态成员函数静态成员函数没有 t h i s this this指针静态成员函数中可以访问其他静态成员但是不能访问非静态的因为没有 t h i s this this指针非静态的成员函数可以访问任意的静态成员变量和静态成员函数突破类yu就可以访问静态成员可以通过 类名::静态成员 或者 对象.静态成员 来访问静态成员变量和静态成员函数静态成员也是类的成员受 p u b l i c public public、 p r o t e c t e d protected protected、 p r i v a t e private private 访问限定符的限制静态成员变量不能在声明位置给缺省值初始化因为缺省值是用来给构造函数初始化列表的静态成员变量不属于某个对象不走构造函数初始化列表。 设已经有A,B,C,D 4个类的定义程序中A,B,C,D构造函数调用顺序为 设已经有A,B,C,D 4个类的定义程序中A,B,C,D析构函数调用顺序为 //AD B A C //BB A D C //CC D B A //DA B D C //EC A B D //FC D A BC c; int main() {A a;B b;static D d;return 0; }选E A、B、C的初始化顺序相信大家都没问题那 D 是什么时候初始化呢 局部的静态变量是在第一次运行到该位置才初始化 选B 首先对 B 和 A后定义的先定义的先析构B 肯定在 A 之前 因为 C 和 D 的声明周期是全局的所以他们的析构肯定在 A 和 B 之后。再先析构 D最后才是 C 3、友元 友元提供了一种突破访问限定符封装的方式友元分为友元函数和友元类在函数声明或类声明前加关键字 f r i e n d friend friend并且把友元声明放到一个类的里面 3.1、友元函数 有些情况函数无法定义在类里面(如不想 t h i s this this指针放在第一个参数位置)但是函数又必须访问类中的成员变量operator详情情看。   怎么办呢这时 C 提供了友元这种突破访问限定符的方式。让类外的函数可以访问类中私有的成员变量 打个比方小刚家有个大泳池小明一直想去小刚家里游泳但他们两人并不熟这时小明肯定无法去游的。怎么办呢小明选择和小刚交往成为小刚的朋友这时小明就可以去小刚家游泳啦    友元函数的基本知识 外部友元函数可以访问类的私有和保护成员友元函数仅仅是一种声明他不是类的成员函数友元函数可以在类定义的任何地方声明不受类访问限定符的限制一个函数可以是多个类的友元函数 友元声明没有明确规定放在哪个位置但一般都是放在类的最上面 // 前置声明都则A的友元函数声明编译器不认识B class B;class A {// 友元声明friend void func(const A aa, const B bb);private:int _a1 1;int _a2 2; }; class B {// 友元声明friend void func(const A aa, const B bb);private:int _b1 3;int _b2 4; }; void func(const A aa, const B bb) {cout aa._a1 endl;cout bb._b1 endl; }一个函数可以成为多个类的友元我多交几个朋友不过分吧 注编译器有一个原则我要用任何类型的变量都要向上找。上述代码要给 c l a s s class class B 一个前置声明否则friend void func(const A aa, const B bb);中 c l a s s class class A 不认识 const B bb中的 B。 3.2、友元类 友元类的基本知识 友元类中的成员函数都是另一个类的友元函数都可以访问另一个类中的私有和保护成员。友元类的关系是单向的不具有交换性比如 A 类是 B 类的友元但是 B 类不是 A 类的友元。友元关系不能传递如果 A 是 B 的友元B 是 C 的友元但是 A 不是 B 的友元。 当一个类需要大量的去访问另外一个类如果仅仅是把成员函数定义成别人的友元会很不方便这时就可以使用友元类。 class A {// 友元声明friend class B;private:int _a1 1;int _a2 2; }; class B { public :void func1(const A aa){cout aa._a1 endl;cout _b1 endl;} void func2(const A aa){cout aa._a2 endl;cout _b2 endl;} private:int _b1 3;int _b2 4; };int main() {A aa;B bb;bb.func1(aa);bb.func1(aa);return 0; }运行结果 友元类就是我的所有成员函数都是你的友元函数 友元类是单向性的上述代码 B 是 A 的友元但 A 不是 B 的友元A 是不能访问 B 中的成员变量的。如果 A 的成员函数也想访问 B 中的成员变量可以在 B 中加入 A 的友元声明这样就可以互相访问啦。 虽然友元提供了便利但是友元会增加耦合度破坏了封装所以友元不宜多用 4.内部类 我们能不能把一个类定义在另一个类的里面呢可以的这就是内部类 class A { private :static int _k;int _h 1; public:class B {public :void foo(const A a){cout _k endl; cout a._h endl; }private:int _b;}; };int main() {cout sizeof(A) endl;return 0; }上述代码中 B 就是 A 的内部类 那么问题来了A 的大小是多少呢它的大小会算上 B 类的大小吗 我们来看下运行结果 可以看到 A 的大小是不计算 B 的 如果一个类定义在另一个类的内部这个内部类就叫做内部类。内部类是一个独立的类跟定义在全局相比他只受外部类类域限制和访问限定符限制所以外部类定义的对象中 不包含内部类。 因为内部类受到外部类的限制所以访问内部类B需要指定类域   它也受 A 访问限定符的限制如果 B 定义在 A 的私有那么外面就无法访问到 B 了。 内部类默认是外部类的 友元类 也就是说默认 B 是 A 的友元B 可以直接访问 A 的私有但 A 无法访问 B 的私有 内部类本质也是一种封装当 A 类和 B 类紧密关联A 类实现出来主要就是给 B 类使用那么可以考虑把 A 类设计为 B 的内部类如果放到 p r i v a t e / p r o t e c t e d private/protected private/protected 位置那么 A 类就是 B 类的专属内部类其他地方都用不了 5、匿名对象 之前我们实例化对象不传参是这样的 int main() {A aa1;//不能这样//因为分不清是实例化还是函数声明A aa2();return 0; }但是 C 还可以这样定义对象 int main() {//传参A();//不传参A(1)return 0; }这样实例化出的是匿名对象而我们之前定义的对象叫做有名对象 匿名对象的声明周期只有当前这一行。一般临时定义一个对象当前用一下即可就可以定义匿名对象 class Solution { public:int Sum_Solution(int n) {//...return n;} }; int main() {Solution aa1;cout aa1.Sum_Solution(10) endl;cout Solution().Sum_Solution(10) endl;return 0; }如想调用 S u m Sum Sum S o l u t i o n Solution Solution 函数但 S u m Sum Sum S o l u t i o n Solution Solution 是成员函数因此正常来讲应定义一个有名对象才能调用。但难免有些繁琐毕竟这里定义对象仅仅是为了调用 S u m Sum Sum_ S o l u t i o n Solution Solution 函数。这时我们就可以使用匿名对象这样就方便多了。 简单来理解匿名对象没有其他的就是为了更方便一点 但是对匿名对象进行引用可以延长匿名对象的生命周期 int main() {//匿名对象是常性用const引用const Solution a Solution();return 0; }6、对象拷贝时的编译器优化 现代编译器为了尽可能提高程序的效率在不影响正确性的情况下会尽可能减少一些传参和传参过程中可以省略的拷贝如何优化 C 标准并没有严格规定各个编译器会根据情况自行处理。当前主流的相对新一点的编译器对于连续一个表达式步骤中的连续拷贝会进行合并优化有些更新更“激进”的编译还会进行跨行跨表达式的合并优化 class A { public :A(int a 0): _a1(a){cout A(int a) endl;} A(const A aa):_a1(aa._a1){cout A(const A aa) endl;} A operator(const A aa){cout A operator(const A aa) endl;if (this ! aa){_a1 aa._a1;} return* this;} ~A(){cout ~A() endl;}private:int _a1 1; };6.1、情况一类型转换 int main() {A aa1 1; return 0; }从语法上来说上述代码会发生隐式类型转换。   先用 1 构造一个临时对象 A类再调用拷贝构造将临时对象赋值给 a a 1 aa1 aa1 运行结果 可以看到经过编译器的优化实际运行结果只有构造并没有调用拷贝构造。 因为编译器认为构造一个临时对象马上进行拷贝中间的临时对象什么都没做太浪费效率。因此省略了中间的临时对象直接构造 a a 1 aa1 aa1。 但下面这种情况就无法省略临时对象 int main() {//引用的是构造的临时对象const A aa2 1;return 0; }6.2、情况二传值传参 void f1(A aa) {}int main() {A aa1(1);f1(aa1);return 0; }我们知道对自定义类型传值传参要先调用其拷贝构造那上述代码有发生优化吗 没有因为构造与拷贝构造并没有发生在一个连续的步骤中所以编译器并没有选择优化 那如果我使用匿名对象呢 void f1(A aa) {}int main() {f1(A(1));return 0; }这样构造和拷贝构造就是在一个连续的表达式的调用里面了 运行结果 按语法逻辑来说应该是先调用构造函数构造匿名对象再传值传参调用拷贝构造   现在经过译器的优化直接合二为一只剩下构造。 注调用析构函数是在出函数作用域调的不是程序结束。虽然过程合二为一但它还是局部变量。    int main() {f1(1);return 0; }这也是同理。       6.3、情况三传值返回 class A { public :A(int a 0): _a1(a){cout A(int a) endl;} A(const A aa):_a1(aa._a1){cout A(const A aa) endl;} A operator(const A aa){cout A operator(const A aa) endl;if (this ! aa){_a1 aa._a1;} return* this;} ~A(){cout ~A() endl;}void Print(){cout A::Print- _a1 endl;}private:int _a1 1; };从语法上来说传值返回会先将返回值拷贝到一个临时对象中再将临时对象拷贝给函数外接收的变量   那么经过编译器优化又会是什么结果呢 A f2() {A aa(1);return aa; } int main() {f2().Print();return 0; }这里我没有选择接收而是用产生的临时对象取调用 P r i n t Print Print 函数 VS2019 运行结果 在VS2019中先构造生成 a a aa aa 后调用拷贝构造产生临时对象。此时出函数作用域 a a aa aa 生命周期结束调用析构函数析构 a a aa aa。临时对象调用 P r i n t Print Print 函数后生命周期结束(临时对象声明周期只在当前行)调用析构函数。    VS2022运行结果 可以看到VS2022的优化是比较激进的。   那他是没有生成临时对象还是没有生成 a a aa aa 呢严格来说是没有生成 a a aa aa 只生成了临时对象。为什么呢我们可以看到析构函数的调用是在 P r i n t Print Print 函数之后此时已经出了函数作用域了。 编译器优化这么“激进”不怕出 b u g bug bug 吗   我们重载一个 再看它优不优化 //前置重载 //A operator() //{ // _a1; // return *this; //}A f2() {A aa(1);aa;//加1看你还优不优化return aa; } int main() {f2().Print();return 0; }可以看到优化还是这么激进可结果居然是对的。   只能说确实牛。 那如果我选择接收呢 A f2() {A aa(1);aa;return aa; } int main() {A ret f2();ret.Print();return 0; }运行结果 现在不仅仅是省略掉了 a a aa aa连临时对象都省略掉了合三为一。直接将结果算好再用 2 去构造 r e t ret ret连 都考虑了。   不过这是 VS2022 太强了一般的编译器走构造-拷贝构造-拷贝构造 或者 构造-拷贝构造 才是正常的。即不优化和优化一级是正常的像 VS2022 这种优化两级的只能说变态。                好啦本期关于类和对象的知识就介绍到这里啦希望本期博客能对你有所帮助。同时如果有错误的地方请多多指正让我们在C语言的学习路上一起进步
http://www.dnsts.com.cn/news/11304.html

相关文章:

  • 艺术设计与制作关键词网站建设优化
  • 做网站设计和推广医疗网站建设讯息
  • 品牌网站和优化网站装饰设计是什么
  • 学校网站建设招聘重庆在线开放平台
  • 网站建设搭配西安网优项目公司
  • 网站开发后怎么进入互联网wordpress正文目录
  • 做加盟代理的网站网站建设维护网页设计
  • 彭州做网站的公司做传媒网站公司名称
  • p2p网站建设方案书南充高端网站建设
  • 抽纸网站建设摘要排名优化工具
  • 营销型网站策划 建设的考试题金华网站如何制作
  • 南宁模板建站定制网站江苏建站服务
  • 营销型网站用什么系统杭州企业宣传画册制作公司
  • 第一ppt模板免费下载网站长沙网站制作哪家
  • 室内设计师网站有哪些oa系统主要干什么的
  • 广州 企业网站建设wordpress即阅文教程
  • 河南第一火电建设公司网站选择一个域名进行网站建设
  • 代做网站地图网页游戏开发技术有哪些
  • 织梦cms建站阿里巴巴手工活外发加工网
  • 网站301重定向代码手机如何安装wordpress
  • 广西新农村建设指导员网站行业网站产品选择
  • 分子信标探针在线设计网站wordpress custom login
  • 建设网站时的常见故障分类安装 wordpress多人
  • 镇海区建设工程安监站网站上海近期大型招聘会
  • vs怎么做网站的首页如何让域名到网站
  • 如何免费学校建网站国外精彩网站
  • 网站案例库2017做那些网站致富
  • 恢复最近删除的网站wordpress数码主题
  • 帝国网站模板建设视频自己做的网站可以卖
  • 西安哪家网络公司做网站网站开发步骤说明书是什么