C++面经|小林coding|(2)
C++ 语言特性
左值和右值的区别?左值引用和右值引用的区别,如何将左值转换成右值?
首先这个问题主要是函数参数 进行 传引用 时 进行的细节优化。
-------左值引用和右值引用
其次是 基类的拷贝构造函数 和 移动构造函数 的区分。
// 拷贝构造函数(深拷贝)Box(const Box& other) {content = new int(*other.content); // 创建新内存std::cout << "拷贝盒子: " << *content << "\n";}// 移动构造函数(关键!)Box(Box&& other) noexcept {content = other.content; // 直接接管资源other.content = nullptr; // 置空原对象std::cout << "移动盒子: " << *content << "\n";}
右值引用(Rvalue References)
T&& t = T(); // t为右值引用
此时T( )创建的就是一个没有名字的临时对象,一创建就销毁了。
与
Base* obj = new Derived();
不同
这个是用new 动态分配内存出来的。不销毁就一直在
std::move() 函数的实现原理是什么?
将左值变为右值
T obj1;
T obj2 = std::move(obj1);// 将obj1标记为右值,调用移动构造函数
若没有move( )
T obj1;
T obj2 = obj1;// 调用拷贝构造函数
什么是模板?如何实现?
- 函数模板 的T是根据实参类型推荐的
- 类模板 要跟一个尖括号< >
Complex a(10 , 20);创建一个Complex类的实例,该Complex类的模板是用int实例化的。
在看这段代码时,将Complex看成一个整体!!!
C++ STL
C++智能指针
介绍一下智能指针?
unique_ptr: 当std::unique_ptr超出作用域 或 被显式释放时,它会自动删除所管理的对象或数组(delete这块内存空间)。
shared_ptr的作用是什么?
我狭义的将 shared_ptr维护的引用计数理解为shared_ptr类中的方法use_count !当use_count=0,就自动销毁对象。这就是引用计数的机制
weak_ptr的作用是什么?如何和shared_ptr结合使用?
消除shared_ptr的循环引用,weak_ptr是弱引用,不是使引用计数+1
一个 unique_ptr 怎么赋值给另一个 unique_ptr 对象?
// 转移所有权std::unique_ptr<Resource> newOwner = std::move(resPtr);
move()就是将左值变成右值,再通过移动构造给左值。
C++内存管理
C++中的内存分区有哪些?
#include <iostream>// 全局区(全局变量)
int globalVar = 100;// 常量区(常量字符串)
const char* constString = "Hello from constant area!";void demoFunction() {// 代码区(函数代码本身存储在这里)// 栈区(局部变量)int stackVar = 200;// 堆区(动态分配内存)int* heapVar = new int(300);std::cout << "=== Memory Areas Demo ===" << std::endl;std::cout << "Global area: " << &globalVar << " -> " << globalVar << std::endl;std::cout << "Constant area: " << static_cast<const void*>(constString) << " -> \"" << constString << "\"" << std::endl;std::cout << "Stack area: " << &stackVar << " -> " << stackVar << std::endl;std::cout << "Heap area: " << heapVar << " -> " << *heapVar << std::endl;// 释放堆内存delete heapVar;
}//代码区
int main() {demoFunction();return 0;
}
如果new内存失败了会是怎么样?
int var=11 | new int(100) | |
---|---|---|
内存分配时机 | 编译时 | 运行时 |
所以new与malloc才叫动态分配内存
C++新特性
lambda表达式的原理是什么?
首先我们知道函数对象
然后lambda就是 匿名函数对象 的一种叫法。clearly
[ ] ( ) -> returntype
{ function-body
}[ ]: 捕获列表。指定 Lambda 表达式如何访问其外部作用域中的变量(值捕获、引用捕获等)。( ): 参数列表。和普通函数的参数列表一样。-> returntype: (可选)返回类型。可以省略,编译器通常会推导返回类型。{ function-body }: 函数体。包含 Lambda 要执行的代码。
delete 函数和 default 函数的区别是什么?A() = default; 默认生成的构造函数长什么样?
A()
{}
C++ 11 nullptr 比 NULL 优势是什么?
fun(NULL)==》fun(0) 0的话会符合void fun(int tmp)这个函数;
但是在C++ 标准有一个特殊规则:整数 0可以被当作空指针常量使用。因此,编译器也可以将 0隐式转换为一个空指针(char const*)。调用fun(char const *p)
所以会产生歧义。
C++代码异常core dump会生成一个栈,里面内容是什么?
- core dump是核心转储,源码发生异常,os会将当时程序崩溃的现场写进core文件中
- 查看崩溃时的调用栈
- 一个源文件发生段错误
#include <iostream>void deepCrash(int level) {// 故意制造一个空指针解引用错误int* ptr = nullptr;*ptr = 42; // 这里会导致段错误
}void middleFunction(int level) {deepCrash(level + 1);
}void topFunction(int level) {middleFunction(level + 1);
}int main() {std::cout << "程序开始运行..." << std::endl;topFunction(1);return 0;
}
#include <iostream>int main() {int* ptr = nullptr; // 空指针,代表ptr指向的是一个内存地址为0的一个特留区域*ptr = 42; // 试图写入空指针指向的内存return 0;
}
- 用GDB查看栈信息时
(gdb) bt
#0 0x0000000000401167 in deepCrash (level=3) at crash_example.cpp:6
#1 0x0000000000401192 in middleFunction (level=2) at crash_example.cpp:10
#2 0x00000000004011b3 in topFunction (level=1) at crash_example.cpp:14
#3 0x00000000004011d4 in main () at crash_example.cpp:18