C++八股文(基础知识篇1)

1. C++ 和 C 有什么区别?

C++是C语言的超集,主要区别在于:

  • 编程范式:C是面向过程的,C++支持面向对象、泛型编程和函数式编程
  • 核心特性:C++增加了类、继承、多态、封装、模板、异常处理、命名空间等
  • 内存管理:C用malloc/free,C++用new/delete,并支持构造/析构函数自动管理资源
  • 类型检查:C++的类型检查更严格
  • 标准库:C++有STL容器、算法和迭代器,功能更强大

2. 引用(Reference)与指针(Pointer)有什么区别?

  • 初始化:引用必须在定义时初始化,指针可以先声明后赋值
  • 重新绑定:引用一旦绑定不能改变,指针可以指向不同对象
  • 空值:引用不能为空,指针可以是nullptr
  • 语法:引用使用更简洁,像操作原变量一样;指针需要解引用操作
  • 内存:引用通常不占额外空间(编译器优化),指针占用内存存储地址
  • 使用场景:引用常用于函数参数传递,指针更灵活,适合动态内存和数据结构

3. 深拷贝与浅拷贝有什么区别?

  • 浅拷贝:只复制对象的值,如果有指针成员,只复制指针地址,不复制指针指向的内容。多个对象共享同一块内存,析构时会导致重复释放
  • 深拷贝:不仅复制对象的值,还会为指针成员重新分配内存并复制内容。每个对象独立管理自己的资源
  • 默认行为:编译器生成的默认拷贝构造函数和赋值运算符执行浅拷贝
  • 何时需要深拷贝:当类中有指针成员、动态分配的资源时,需要自定义深拷贝

4. 什么是构造函数和析构函数?

  • 构造函数:对象创建时自动调用,用于初始化对象。函数名与类名相同,无返回值。可以重载,支持默认参数和初始化列表
  • 析构函数:对象销毁时自动调用,用于清理资源(释放内存、关闭文件等)。函数名是~加类名,无参数无返回值,不能重载
  • 调用时机:栈对象离开作用域时、delete堆对象时、程序结束时全局对象销毁
  • 虚析构函数:基类析构函数应该是虚函数,确保通过基类指针删除派生类对象时正确调用析构函数

5. 如何定义常量(const)?

  • 常量变量const int MAX = 100; 必须初始化,不能修改
  • 常量指针const int* p 指向常量,不能通过p修改值;int* const p 指针本身是常量,不能改变指向
  • 常量引用const int& ref = value; 常用于函数参数,避免拷贝且防止修改
  • 常量成员函数void func() const; 承诺不修改成员变量,可被常量对象调用
  • 编译期常量constexpr int SIZE = 10; C++11引入,编译时求值

6. new 和 delete 是如何工作的?

  • new的工作:①分配内存(调用operator new)②调用构造函数初始化对象③返回指向对象的指针
  • delete的工作:①调用析构函数②释放内存(调用operator delete)
  • 数组形式new[] 分配数组,delete[] 释放数组,必须配对使用
  • 失败处理:new失败抛出bad_alloc异常,可用nothrow版本返回nullptr
  • 与malloc/free区别:new/delete会调用构造/析构函数,malloc/free只管理内存

7. sizeof 和 alignof 的作用是什么?

  • sizeof:编译期运算符,返回类型或对象占用的字节数。对数组返回总大小,对指针返回指针本身大小(通常4或8字节)
  • alignof:C++11引入,返回类型的对齐要求(字节数)。CPU访问对齐的数据更高效
  • 结构体大小:受内存对齐影响,可能有填充字节,不是简单的成员大小相加
  • 使用场景:sizeof常用于内存分配、数组元素计数;alignof用于底层内存布局优化

8. 默认构造函数和拷贝构造函数有什么区别?

  • 默认构造函数:无参数或所有参数都有默认值,用于创建对象。MyClass obj; 如果没定义任何构造函数,编译器会生成
  • 拷贝构造函数:参数是同类型对象的引用,用于用已有对象初始化新对象。MyClass obj2(obj1);MyClass obj2 = obj1;
  • 调用时机:拷贝构造在对象作为函数参数传递、函数返回对象、用对象初始化另一对象时调用
  • 编译器生成:如果不定义,编译器会生成默认版本,执行成员逐个拷贝

9. const 关键字的用途是什么?

  • 定义常量:防止变量被修改,提高代码安全性
  • 函数参数void func(const string& str) 避免拷贝开销且保证不修改实参
  • 成员函数int getValue() const 表明不修改对象状态,常量对象只能调用const成员函数
  • 返回值const int* getPtr() 防止返回值被修改
  • 编译优化:编译器可以对const进行优化,提高性能
  • 接口设计:明确表达设计意图,增强代码可读性和可维护性

10. 如何使用 static 关键字?

  • 静态局部变量:函数内的static变量只初始化一次,生命周期是整个程序,但作用域仅在函数内
  • 静态全局变量/函数:限制作用域在当前文件,实现文件级封装,避免命名冲突
  • 静态成员变量:属于类而非对象,所有对象共享,必须在类外初始化
  • 静态成员函数:不依赖具体对象,只能访问静态成员,通过类名调用
  • 使用场景:单例模式、计数器、工厂方法、工具函数等

C++八股文全集 文章被收录于专栏

本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。

全部评论

相关推荐

昨天 20:12
已编辑
合肥工业大学 后端工程师
鼠鼠大二上的时候听说直接学应用层好找工作,于是all in 应用层,后面学着感觉非常难受,大二下结束的时候就放弃了,大二的那个暑假学了下C语言和离散数学,大三上的时候好好想了想自己到底应该选择哪个方向。现在复盘了一下,为什么当时学应用层技术会感觉很难受呢?目前认为是因为搞错了学习顺序,没有先学计算机基础,就直接学应用层知识。这就好像直接在面前放一个专用计算机,完全不知道它的底层运行原理是什么,就直接对它进行黑盒调试。如果先学计算机基础,就相当于学习了一个通用操作系统的底层原理,后面去理解专用操作系统,只需要修改一些参数就可以了。所以我的结论是:其实应用层的很多知识都是源自计算机基础知识的,学好计算机基础知识后,学任何应用层知识都会很快。所以如果让我重来一次,我会这样学(就业导向,未经实践检验,慎用):0.C语言,顺势学一丢丢C++(class和STL就ok,不然耗时太长。体验面向对象,后面根据兴趣选择cpp或java或js或go或else深入学习)1.数据结构与算法,手写常见数据结构,会写Leetcode hot 1002.计算机组成原理,理解CPU、内存、磁盘、设备之间的关系3.操作系统,理解并发,内存,文件,磁盘。4.计算机网络,理解网络分层架构,理解常见的协议。5.数据库,会写SQL,知道怎么用程序操控mysql、redis。学到这里计算机基础就基本学完了,其实还有一些课没学,比如数字电路、编译原理、离散数学、汇编语言...,但是这些课不如四大件+数据库更实用。可以跟学计算机基础并行的是兴趣探索,选择感兴趣的方向深入,比如前端、后端、测试、算法...这样操作的话,选择任何方向,万变不离其宗,都因为有很好的计算机基础,学得很快,它们都是互相关联的,就像用一个泛型去代替任意数据类型,编译或者运行的时候才替换成真正的数据类型。当理解了底层,就不一定要去和几百万人卷供过于求的红海。可以去玩图形学、编译器、内核开发,进入那些门槛高、护城河深、也更有趣的领域。当然,不是学了cpp后面就一定要搞cpp,而是为了借cpp之手了解底层知识,个人认为无论走哪个方向,了解底层知识都是必要的。虽然我推崇基础,但并不意味着完全不看应用层。建议比例是 70% 基础 + 30% 应用兴趣探索。基础决定你的上限,但应用层技术却是你的入场券。
点赞 评论 收藏
分享
完了_我学不完了:老哥啥时候进的评估呀俺是云三
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务