C++八股_C和C++基础知识
1、C++内存空间的划分答:C++ 程序的内存布局(地址从低到高)通常为:代码区 → 常量存储区 → 全局 / 静态存储区 → 堆 → 栈(堆和栈之间存在空闲区域,避免溢出冲突)。①、代码区:存放函数体的二进制机器指令;②、常量存储区:存放不可修改的常量数据;③、全局 / 静态存储区:统一存储全局变量和静态变量;④、堆(Heap):存放程序运行时手动分配的动态内存;⑤、栈(Stack):存放函数局部变量(如int a)、函数参数、返回地址等临时数据;⑥、线程局部存储区(C++11新增):线程独立、自动分配 / 释放。★2、智能指针答:在 C++ 中,智能指针是一种封装了原始指针的类模板,设计目标就是管理堆上动态分配的内存,避免内存泄漏(分配的内存没被释放)和悬垂指针(指针指向的内存已经被释放,但指针本身没有被置空)等问题。auto_ptr(由于标准容器赋值后,原对象被释放,违背C++设计原则,c++11废弃),unique_ptr,shared_ptr,weak_ptr;①、unique_ptr:“独占 + 可移动 + 自动释放”,独占的意思一份资源只能对应一个unique_ptr指针,这个资源可以从unique_ptr指针移动给另一个unique_ptr指针,但移动后,被移动的指针会置空;②、shared_ptr:共享所有权,引用计数归零才释放;③、weak_ptr:为了解决shared_ptr陷入循环引用,引入的智能指针;④、shared_ptr是否线程安全:当多个shared_ptr指向同一块内存空间时,所有shared_ptr的引用计数是线程安全的,不会出现引用计数少加或者多加的情况,因为底层的引用计数是原子操作;但是当不同的shared_ptr访问同一块内存空间进行IO操作时,需要加锁才能保证访问内存空间时线程安全。★3、左值和右值【C语言中有右值,没有右值引用。右值引用(T)是 C++11标准 引入的特性】①、左值和右值的定义答:左值在赋值运算符左边,有名称,有内存地址;右值在赋值运算符右边,没有名称,没有内存地址,右值有两种,一种是纯右值(字面量、表达式计算结果),一种是将亡值(即将被销毁的对象,资源可以被转移,比如函数返回的局部变量),右值用完立即销毁。【只有右值引用没有右值指针的原因就是因为右值没有地址】②、左值引用和右值引用的作用答:左值引用(类型)就是左值的 “别名”,操作引用等价于操作原对象;右值引用(类型)【右值引用有名称有地址,其本身是左值,区别万能引用T】,用于延长右值的生命周期(本来一个表达式结果在下一句代码中就会失效,但是如果把它作为右值传递给右值引用,那么这个右值引用的生命周期内,表达式结果一直有效)、支持移动语义(“偷” 走右值的资源,避免不必要的拷贝)、实现完美转发(同一模板函数可以处理左值和右值)。③、C++中的move函数作用?答:move函数是将一个左值 “转换为右值引用类型”,本质是给编译器一个 “语义标记”:这个对象可以被 “移动”(即允许接收方偷取其内部资源),触发移动语义,避免拷贝。④、什么是移动语义?答:移动语义是 C++11 引入的核心优化机制,核心目标是 “避免不必要的拷贝(拷贝语义需要开辟额外内存空间),直接转移对象的内部资源”;实现方法是让接收对象指针指向被接收对象的内存地址,释放原来指向被接收对象的指针。⑤、为什么需要完美转发,如何实现完美转发?答:完美转发是解决 “模板函数传递参数时,如何保留参数原始值类别(左值 / 右值)” 的问题而设计的方法;实现完美转发最核心的机制是万能引用(T)和std::forward(a);没有 std::forward,无论传入的实参是左值还是右值,函数内部的参数都会被当作左值处理。#includeiostream#includeutility// std::forward 的头文件voidli(inta){std::cout""std::endl;}voidli(inta){std