
大家好我是Halcyon.平安欢迎文末添加好友交流共同进步目录C中值传递和引用传递的区别C与C的区别什么是C的左值和右值它们有什么区别什么是C中的移动语义与完美转发什么是C的列表初始化C中的move有什么作用原理是什么介绍C三种智能指针的使用场景C11中有哪些常用的新特性C中static的作用什么场景下用staticC中const的作用谈谈你对const的理解目录C中值传递和引用传递的区别值传递值传递会触发一次拷贝的动作并且对参数的修改不会影响原始值。对象大的话效率低。引用传递只是一个参数的引用不会触发拷贝动作效率高。但是修改参数会直接作用于原始值。大对象推荐用 const 引用既能避免拷贝又不会被修改C与C的区别六个方面面向过程与面向对象C语言是面向过程的主要是通过函数来解决问题自己造轮子C主要是面向对象的主要是使用类和对象组织代码使用造好的轮子继承C语言没有继承的概念C允许继承且可以一个子类继承多个父类函数重载C语言不支持函数重载函数名必须不一样C支持函数重载支持类型和参数个数不同的重载模板C语言不支持模板C支持模板且有静态和动态的多态内存管理C语言使用的是malloc与free用于申请和释放内存C使用的是new和delete进行内存管理也可以用智能指针标准库C的标准库比C语言的标准库丰富很多比如vector/string/map等等什么是C的左值和右值它们有什么区别左值赋值运算符的左边有自己的地址空间一般是有名字的变量右值赋值运算符的右边没有自己的地址空间一般是常量、临时值或表达式求值结果区别一个在等号左边一个在等号右边 / 一个可以取地址且有名字另一个不可以取地址且没有名字补充C11 把右值又细分为纯右值prvalue和将亡值xvalue了解即可。什么是C中的移动语义与完美转发首先它们都是C11引入的新特性移动语义std::move常规的资源管理是拷贝别人的资源而移动语义直接是转移资源的所有权性能更好移动构造和移动复制实现的#includeiostream#includestringusingnamespacestd;intmain(){string a123;// 拷贝复制一份字符串两份内存string ba;// move把a的内存所有权转移给ca变空所以不能再随意读取了无复制string cmove(a);coutaendl;// 空coutbendl;// 123coutcendl;// 123return0;}完美转发std::forward可以写一个接收任意实参的函数模板并且转发到其它函数目标函数会收到与转发函数完全相同的实参转发函数的实参是左值那目标函数的实参也是左值同理转发函数实参是右值那目标函数实参也是右值#includeiostreamusingnamespacestd;// 重载1接收左值 intvoidtest(int){cout左值\n;}// 重载2接收纯右值 intvoidtest(int){cout右值\n;}// 模板函数T 万能引用templatetypenameTvoidf(Tx){test(forwardT(x));}intmain(){intx1;f(x);// 传入左值变量f(100);// 传入临时字面量右值return0;}//输出结果//左值//右值什么是C的列表初始化这也是C11新引入的就是可以用{}进行初始化变量或者对象。并且可以防止类型窄化避免丢失精度的隐式类型转化inta{10};//////////////////////////////////intarr[3]{1,2,3};/////////////////////////////////classPoint{public:intx,y;Point(inta,intb):x{a},y{b}{}};Point p{1,2};// 使用花括号初始化对象///////////////////////////////////std::vectorintvec{1,2,3,4};//////////////////////////////////intx{3.14};// errorfloat转int会触发类型窄化C中的move有什么作用原理是什么作用它是将对象的资源从一个对象转移到另一个对象然后之前的对象就变为空这样就无需进行深拷贝减少资源内存的分配提高性能原理// movetemplateclassTLIBC_INLINEconstexprcpp::remove_reference_tTmove(Tt){returnstatic_casttypenamecpp::remove_reference_tT(t);}1. T t是万能引用并不是单纯的右值引用 2. 传入左值的话T推到左值为x参数变为x 折叠后为x(左值引用)传入右值的话T推到类型为x参数变为x 3. 然后我们看C引用折叠标准 → → → → 4. cpp::remove_reference_tT 去引用,把类型所有引用左值 、右值 全部剥离得到原始裸类型 5. move 函数返回值cpp::remove_reference_tT 不管 T 原来带不带引用先全部剥掉再强行拼接右值引用 。 所以返回值类型永远是裸类型的右值引用 X。所以我们从源码知道就是无论输入的是左值还是右值都会强制的转成右值。说白了move 啥也没搬只是个强制类型转换真正的搬运活在移动构造/移动赋值里。介绍C三种智能指针的使用场景std::unique_ptr独占所有权指针意思就是同一时间内只有一个unique_ptr指向一个特定的对象这个指针被销毁的时候指向的对象也会被销毁。场景一个对象只能被一个指针所拥有的时候需要自动管理资源堆对象、文件句柄等。std::shared_ptr共享所有权的指针多个shared_ptr可以指向同一个对象。内部的引用计数来确保只有当最后一个指向对象的shared_ptr被销毁的时候对象才被销毁。场景多个所有者共享对象的时候需要通过复制构造函数或赋值操作符来复制智能指针时候。std::weak_ptr不拥有所有权的指针用来解决共享智能指针中的循环引用问题。场景解决共享智能指针中的循环引用问题需要使用但不拥有由共享指针管理的对象的时候C11中有哪些常用的新特性auto类型推导这样就不用手写复杂类型了编译器会直接根据右侧的表达式自动推导出变量类型智能指针独占、共享、无所有权解决循环引用自动释放堆内存std::thread标准的多线程这样我们就不再需要跨平台左值右值std::function和lambda表达式function用来统一包装任意可调用的对象可以解决回调统一存储的问题lambda语法[捕获列表](参数)mutable - 返回值 {函数体}移动语义、完美转发RAII lock:资源在构造的时候获取在析构的时候自动解锁lock_guard不能手动解锁unique_lock可以C中static的作用什么场景下用static作用修饰局部变量改变的是生命周期存在静态区函数结束也不销毁但作用域还在函数内部下次调用还能保持上次的值修饰全局变量/函数把作用域限制在本文件内不允许跨文件使用也叫内部链接性修饰类的成员变量/函数让整个类的对象共享这一份成员所有对象共用几个注意点静态成员变量需要在类外定义C17 的inline除外静态成员函数没有 this 指针只能访问静态成员不能访问普通成员C中const的作用谈谈你对const的理解修饰变量必须初始化且之后不能再被修改相当于只读修饰指针const int* p指针指向的数据不能改指针本身可以改常量指针int* const p指针本身不能改指向的数据可以改指针常量记忆口诀const 在*左边修饰数据在*右边修饰指针修饰引用const T常用于函数参数避免拷贝又保证不被修改最常用修饰成员函数写在函数声明后面表示这个函数不会修改任何成员变量const 对象只能调用 const 成员函数const 重载参数是T和const T可以构成重载成员函数的 const 版本和非 const 版本也可以构成重载