当前位置: 首页 > news >正文

C++知识点复习(面向面试6)

今天是第六天了也是终于快复习一半了,为自己鼓鼓掌。今天依旧是五条知识点,一起来查漏补缺吧。

26.类和结构体什么区别?

27.被 deletefree释放的内存会直接返还给操作系统吗?

28.什么时候需要析构函数?

29.常函数内能否修改静态成员?

30.初始化参数列表什么特点

好的,我们从第二十六条开始。

26.类和结构体什么区别?

语法层面:只有两个默认权限不同

在 C++ 中,classstruct在功能上几乎是 100% 相同的(都可以包含成员变量、成员函数、构造/析构函数,也都支持继承和多态)。它们唯二的硬性语法区别在于:

  1. 默认访问权限不同
    • class的默认访问权限是private(私有)。
    • struct的默认访问权限是public(公开)。
  2. 默认继承权限不同
    • class继承默认是private继承。
    • struct继承默认是public继承。

27.被 deletefree释放的内存会直接返还给操作系统吗?

不会,会被存放在内存池中,下次申请内存时直接去内存池中查找,解决了内存碎片问 题。(一般公司不会问的知识点,曾经拼多多,腾讯等问过想了解搜索 ptmalloc的实现)

如何主动将内存还给操作系统?

如果面试官继续深挖:“如果程序长时间运行,产生了大量空闲内存但都没还给系统,导致进程占用内存(RSS)居高不下,该怎么办?”

  • 解决方案:可以调用 glibc 提供的非标准函数malloc_trim(0)
  • 作用:它会尝试强制将堆顶(top chunk)连续的空闲内存通过brk(-size)系统调用收缩并归还给操作系统。但需要注意,如果堆顶内存不连续(比如被一些未释放的小对象挡住),这个操作可能会失败或只能归还部分内存。、

28.什么时候需要析构函数?

需要手写析构函数的根本原因是“类内部申请了需要手动释放的资源(堆内存、文件句柄、网络连接等)”。并且,一旦手写了析构函数,一定要警惕默认的浅拷贝带来的双重释放风险,遵循“三/五法则”来完善类的拷贝和移动语义。

1. 动态分配的内存(最典型)

当类的成员变量中,有通过newnew[]或 C 语言的malloc等函数在堆区申请的内存时,必须在析构函数中使用deletedelete[]free来释放。

  • 举例:你提到的指针成员char* mName = new char[100];,如果不在析构函数中delete[] mName;,就会导致内存泄漏。

2. 系统资源句柄(极易被忽略)

除了内存,程序在运行中打开的各类系统资源,如果不关闭,会导致资源泄漏,甚至影响整个系统的正常运行。这些资源通常不是通过new分配的,但也必须在析构函数中手动关闭。

  • 打开的文件:通过fopen打开的文件指针(FILE*),需要在析构中调用fclose关闭。
  • 网络连接/数据库连接:比如 Socket 套接字、数据库连接句柄等,需要在析构中调用close或专门的断开连接函数。
  • 互斥锁/信号量:在多线程编程中,如果类持有锁,需要在析构中确保锁被正确释放,防止死锁。

3. 自定义类型成员需要特殊清理时

如果类中包含其他自定义类型的成员,且这些成员本身管理着上述资源,通常这些成员自己的析构函数会处理清理工作。但如果你需要控制它们的销毁顺序,或者进行一些额外的联动清理操作,也需要手写当前类的析构函数。

  • 补充机制:如果类中全是intdoublestd::string这种自带完善析构机制的成员,编译器生成的默认析构函数就完全够用了,此时不需要手写。

💡 面试核心加分项:析构函数与“三/五法则”

在面试中,当你回答了“什么时候需要析构函数”后,面试官紧接着大概率会追问:“如果你手写了析构函数,还需要注意什么?”

这时你可以抛出 C++ 著名的“三法则(Rule of Three)”或 C++11 后的“五法则(Rule of Five)”

  • 核心逻辑:如果你需要手写析构函数,说明你的类在手动管理资源。那么,编译器自动生成的拷贝构造函数拷贝赋值运算符(浅拷贝)大概率是错误的。
  • 潜在风险:默认的浅拷贝会导致两个对象的指针成员指向同一块堆内存。当其中一个对象被销毁(调用析构函数释放内存)后,另一个对象的指针就会变成“野指针”,再次析构时会引发重复释放(Double Free),导致程序崩溃。
  • 正确做法:一旦手写了析构函数,通常也必须显式手写(或禁用)拷贝构造函数和拷贝赋值运算符,来实现深拷贝或禁止拷贝。在 C++11 以后,还需要考虑移动构造函数和移动赋值运算符。

29.常函数内能否修改静态成员?

可以,常函数内不能修改非静态成员,因为访问非静态成员需要使用this指针,例如:在 类 A中的一个常函数内this指针的类型为 :const A* const this; *thisconst修饰代表不能 通过 this指针修改对象,我门在访问非静态成员时需要使用this指针,所以不能修改,访问静 态成员时不需要使用 this指针区分是哪个对象的成员,因为静态成员是共享的单独存放在静态 区不占对象的内存,所以常函数内可以修改静态成员。
30.初始化参数列表什么特点

●构造函数和类名相同,没有返回值也不写 void
●如果没有实现构造函数编译器会提供默认的无参构造函数
●构造函数是给成员变量赋值的不是初始化(引出初始化参数列表)
●移动构造,继承构造,委托构造(C++11后的写法,更加简洁高效)

#include <iostream> #include <string> // 1. 模拟一个没有默认构造函数的类(作为成员对象) class Engine { public: Engine(int horsepower) : m_horsepower(horsepower) { std::cout << "Engine 构造函数被调用,马力: " << m_horsepower << std::endl; } private: int m_horsepower; }; // 2. 父类(没有默认构造函数,强制子类在初始化列表中调用) class Vehicle { public: Vehicle(std::string brand) : m_brand(brand) { std::cout << "Vehicle 父类构造函数被调用,品牌: " << m_brand << std::endl; } private: std::string m_brand; }; // 3. 子类 Car,包含 const、引用、无默认构造成员 class Car : public Vehicle { public: // 构造函数:演示初始化列表的各种用法 Car(std::string brand, int hp, int& yearRef) : Vehicle(brand), // 特点5:调用父类的带参构造函数 m_engine(hp), // 特点4:调用成员对象 Engine 的带参构造函数 m_maxSpeed(220), // 特点3:const 常量必须在初始化列表中初始化 m_yearRef(yearRef) // 特点3:引用成员必须在初始化列表中绑定 { std::cout << "Car 子类构造函数体执行" << std::endl; // 注意:如果在这里写 m_maxSpeed = 220; 或 m_yearRef = yearRef; 编译器会直接报错! } void display() { std::cout << "当前引用的年份: " << m_yearRef << std::endl; } private: int m_maxSpeed; // const 常量成员 int& m_yearRef; // 引用成员 Engine m_engine; // 没有默认构造函数的成员对象 // 演示初始化顺序的坑: int m_a; int m_b; }; int main() { int currentYear = 2026; std::cout << "--- 开始创建 Car 对象 ---" << std::endl; // 传入品牌、马力、以及一个外部变量的引用 Car myCar("Tesla", 500, currentYear); myCar.display(); return 0; }
http://www.zskr.cn/news/1395395.html

相关文章:

  • 一个真正“隐私友好”的 AVIF 转 JPG 在线工具(无需上传文件)
  • IS215UCCCS05A单板计算机
  • 2025-2026年企业展厅设计公司推荐:五大排行评测科技展厅交互体验性价比高注意事项
  • win11打开软件,显示在后台运行
  • 开源协作机械臂OpenArm:如何用模块化设计打破机器人研发的壁垒
  • 文件无法保存,改如何解决呢?
  • 从文件柜视角解析RAG:构建高效检索增强生成系统的工程实践
  • 从被动微调到主动召回:基于Transformer内部知识库的医学缩写消歧新范式
  • 彩言 ERP + EIP 一站式对接
  • 靠谱的TIG热丝堆焊设备厂家
  • Taotoken用量看板如何帮助个人开发者清晰掌控月度支出
  • 番茄小说下载器完整指南:从文字到音频的多平台解决方案
  • Lovable功能更新计划深度拆解(仅限早期测试团队内部披露)
  • 跨越设计鸿沟:PADS 2.6 至 Allegro 17.2 的精准迁移与实战解析
  • Switch-Toolbox终极指南:任天堂游戏文件编辑的完整解决方案
  • 中小企业如何利用Taotoken统一管理多个AI项目的API密钥与用量
  • # 20252920卢兴宇 2025-2026-2 《网络攻防实践》第九次作业
  • 520 西交利物浦 AI 沙龙火爆!超集信息解锁企业AI降本增效新密码
  • 直销选哪家?伍福家园产品好
  • ChatGPT引用格式生成器失效了?深度拆解arXiv/SSRN/ACM三大平台隐性规则(独家逆向工程报告)
  • 博士生紧急必读:ChatGPT辅助写作的学术红线清单(教育部2024新规+12所双一流高校AI使用细则对比)
  • 政校企社协同发力:抚顺市望花区“AI+OPC”联合培育行动在辽宁石油化工大学启动
  • 打破时间反演对称性不靠强光也不靠强磁——《Nature Communications》报道一种可集成的太赫兹手性腔
  • 网络安全的现状如何了?怎么看待如今的网络安全圈子?
  • 哈尔滨卖翡翠还在踩坑?7家实测帮你锁定靠谱渠道 - 奢侈品回收测评
  • 三菱A系列老旧PLC通过以太网桥接器实现MES系统无缝对接与数据互通
  • pandas数据处理实战:从环境搭建到清洗分析全流程
  • 3分钟掌握:如何在Blender中无缝处理3D打印文件
  • 网站流量突然下降?先学会用 Search Console 排查问题
  • Topit:重新定义Mac窗口置顶,打造无缝多任务工作流