网站资讯建设,用dw建设网站,休闲农业有哪些网络营销方式,网站开发立项文章目录 前言
本文记录C一些面试难点问题剖析。 1. 左右值和右值引用的作用
左值#xff1a;可以在左边#xff0c;表达式结束后依然存在的持久对象#xff0c;一般有名字#xff0c;可以取地址。 提示#xff1a; 前置自加/自减 可以做左值#xff1b; 右值在右边一些面试难点问题剖析。 1. 左右值和右值引用的作用
左值可以在左边表达式结束后依然存在的持久对象一般有名字可以取地址。 提示 前置自加/自减 可以做左值 右值在右边不能取地址没有名字临时对象。 提示 后置自加自减 做右值 但是右值分两种 纯右值字面值后置自增自减算术表达式返回非引用的函数调用 将亡值与右值引用相关的表达式。例如将要被移动的对象 右值引用 语法: 数据类型 变量名 右值 。就是给右值取个名字但是右值引用本身变成了左值。 作用1. 实现移动语义 2. 实现完美转发 左值引用 例如 int a0; int b a; 这是普通左值引用 const int c 0; 这是常量左值引用必须要有const否则报错。 所以常量左值引用可以接收常量右值也就是字面值。 移动语义
C 11实现移动语义来减少拷贝 对右值使用移动语义可以减少拷贝对左值可以使用std::move将左值转义为右值。
完美转发 万能引用 T 以此为形参可以接收左值和右值。 提示 T必须这么写也就是只能用在模板中。如果写成int 做形参那只能接收右值。 对右值引用的两个规则中的第一个也同样影响了旧式的左值引用。回想在pre-11 C时对一个引用取引用是是不被允许的比如A 会导致一个编译器错误。相比之下在C11中引入了如下所示的引用折叠规则reference collapsing rules 1. A 变成A 2. A 变成A 3. A 变成A 4. A 变成A 模板函数std::forwardT(参数)用于转发参数如果参数是右值转发完是右值引用如果是左值则转发后是左值引用。C11 forward完美转发_Barry__的博客-CSDN博客_c forward 上述文章解释了完美转发的使用场景和更合理的解释。
2. 智能指针
unique_ptr
独占式拥有保证同一时间只有一个智能指针指向该对象。 #includeiostream
#includememory
using namespace std;
int main(){unique_ptrint up_x(new int(10));//unique_ptrint up_x2(up_x); //没有左值拷贝构造函数//unique_ptrint up_x2up_x; //没有左值拷贝构造函数unique_ptrint up_x2;//up_x2 up_x; //没有左值拷贝赋值运算符因为已被deleteunique_ptrint up_x3(unique_ptrint(new int(9))); //有右值拷贝构造up_x2 std::move(up_x);//可以借助move将up_x赋值给up_x2.此操作完成后up-x不可用有右值拷贝复制*up_x2 99;////*up_x 22;return 0;
}
shared_ptr
多个智能指针共享指向一个对象所指对象在最后一个引用被销毁时释放 可以使用make_shared函数通过构造函数传入普通指针get函数获得普通指针。
默认情况下初始化智能指针的普通指针必须指向一个动态分配的内存因为智能指针默认调用delete释放内存。但也可以将智能指针绑定到一个类类型但是必须正确定义它的析构函数。例如shared_ptrT p(q,d);d为自定义的析构函数对象。注意事项shared_ptr可以指向数组但是需要自定义删除器 关于数组的使用和指派删除器: 我们经常看到的例子都是单个对象那数组是不是也可以像这样shared_ptrint sp(new int[10])使用shread_ptr? 这样是错误的。我们要使用shared_ptr管理数组的话必须给其制定一个删除器函数 shared_ptrint sp(new int[10], [](int *p) {delete[] p; }); 这里的匿名函数即是删除器。 如果没有提供删除器这段代码就是未定义的。默认情况下shared_ptr使用delete销毁它所指的对象。如果这个对象是个动态数组对其使用delete所产生的问题和释放一个动态数组忘记加[]的后果相同。 构造函数是explict的所以不存在从内置指针到智能指针的隐式类型转换。因此必须使用直接初始化显式。share_ptr循环引用导致的内存泄漏
#includeiostream
#includememory
using namespace std;
namespace demo63 //演示智能指针循环引用的问题
{class P2;class P1{public:std::shared_ptrP2 P2Ptr; //如果换成weak_ptr的就可以打破僵局P1() {cout hello P1 endl;}~P1() {cout bye P1\n;}};class P2 {public:std::shared_ptrP1 P1Ptr; //如果换成weak_ptr的就可以打破僵局P2() {cout hello P2\n;}~P2() {cout bye P2\n;}};
}
int main()
{using namespace demo63;//shared_ptrint sp();//shared_ptrint sp(new int[10], [](int *p) {delete[] p; });{shared_ptrP1 p1p(new P1());cout p count : p1p.use_count() endl;shared_ptrP2 p2p(new P2());cout c count : p2p.use_count() endl;p1p-P2Ptr p2p;cout c count : p2p.use_count() endl;p2p-P1Ptr p1p;cout p count : p1p.use_count() endl;}//退出循环后p1p和p2p释放他们只是指针而已所以会调用一次智能指针的析构函数//当p1p要析构的时候发现本身还被p2p-P1Ptr指着所以对p2p()的引用只是减一p1p就析构了不存在了//当p2p要析构的时候发现本身被先前p1p的P2Ptr指针引用这所以只是引用减一然后p2p被销毁。//而此时对象P2和P1都没有被释放内部的P1Ptr指针和P2Ptr指针还在相互指向着对方。导致内存泄露return 0;
} PS D:\MyCode cd d:\MyCode\ ; if ($?) { g main.cpp -o main } ; if ($?) { .\main } hello P1 p count :1 hello P2 c count :1 c count :2 p count :2 weak_ptr: 总结
提示这里对文章进行总结
例如以上就是今天要讲的内容本文仅仅简单介绍了pandas的使用而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。