c++常考
一、左值和右值
右值分为纯右值和将亡值。
纯右值是表达式、返回的临时变量值。
将亡值是右值引用,右值引用指向右值,可以获取的地址就是临时变量的地址。
右值引用使得右值重生,右值变量的声明周期和右值引用变量的一样,只要右值引用变量存在,就能使得右值变量活着。
左值引用指向左值,右值引用指向右值。左值引用和右值引用都是左值。
带右值引用参数的拷贝构造和赋值重载函数,又叫移动构造函数和移动赋值函数,这里的移动指的是把原始量的资源移动给拷贝后的,原始不持有资源,为nullptr了。
移动构造:临时对象(源对象)被拷贝之后就不需要用了,所以不需要复制构造这种操作,完全可以把临时对象的资源直接移动,这样就避免了多余的复制构造。
二、c++构造函数不能是虚函数
第一,在创建对象的时候是调用构造函数,要确定对象的类型。但是虚函数是在运行的时候确定类型的。所以在构造一个对象的时候,编译器会无法知道对象的类型。
第二,虚函数的调用需要通过虚函数表上的虚函数指针,这个指针是存放在对象的内存空间中的。对象没被创建就没有内存空间,那就没有对应的虚函数指针,那就找不到对应的虚构造函数。
第三,虚函数是为了多态而生的,多态就是父类的指针指向或引用子类,在调用的时候通过动态联编调用子类重写的虚函数。但是构造函数是在创建对象的时候系统自动调用的,不可能通过父类或者引用去调用,所以即使构造函数是虚函数也没有意义。
三、push_back和emplace_back的区别
创建一个匿名对象传入,如果使用push_back是先创建一个临时对象,然后调用移动构造函数把临时对象的副本拷贝到容器末尾增加的元素中,然后再调用析构函数释放临时对象。
如果使用emplace可以不用传入匿名对象,而是直接传入对象构造所需要的参数。直接调用构造函数在容器末尾添加一个元素。
即同样是在容器尾部添加一个元素,emplace_back比push_back少了一次对象的构造和析构。所以,emplace_back比push_back更高效。
int main() { vector<MyTest> vec; vec.reserve(2);//预先分配内存 cout << "push_back:" << endl; vec.push_back(MyTest(1, 20)); cout << "emplace_back:" << endl; vec.emplace_back(1, 20); //只有在只传对象参数的情况下才能只调用构造函数提高效率 //vec.emplace_back(MyTest(1, 20)); //如果也是传整个对象,也是要调用拷贝构造函数,无法提高效率。 return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下