嵌入式八股-C++面试30题(20240814)

1. 单继承和多继承的虚函数表结构

  • 单继承:在单继承中,每个类如果包含虚函数(或从父类继承虚函数),编译器会为这个类创建一个虚函数表(vtable)。类的每个对象都包含一个指向这个虚函数表的指针,称为虚表指针(vptr)。vtable中包含了类的所有虚函数的地址。
  • 多继承:在多继承的情况下,由于一个类可以从多个基类继承,可能存在多个vtable。如果基类中都有虚函数,子类的对象会包含多个vptr,分别指向不同基类的vtable。为了正确调用虚函数,编译器需要处理不同基类的vptr指向及偏移。

2. C++ 程序编译过程

C++程序编译过程通常分为以下几个步骤:

  1. 预处理(Preprocessing):处理宏定义、头文件包含、条件编译等指令。
  2. 编译(Compilation):将预处理后的代码翻译成汇编代码。
  3. 汇编(Assembly):将汇编代码转换为机器代码,生成目标文件(object file)。
  4. 链接(Linking):将目标文件与库文件链接,生成可执行文件。

3. C++ 内存管理

C++提供了多种内存管理方式,包括静态内存分配、栈内存分配和堆内存分配。

  • 静态内存:全局变量、静态变量,生命周期贯穿程序整个运行过程。
  • 栈内存:局部变量、函数调用栈,生命周期由作用域决定,自动管理。
  • 堆内存:动态分配的内存,通过newdelete来管理,需手动释放。

4. 栈和堆的区别

  • :由编译器自动管理,速度快,存储局部变量,作用域结束时自动释放。
  • :由程序员手动管理(通过newdelete),灵活性高,适合动态内存需求,但易引发内存泄漏。

5. 变量的区别

  • 局部变量:定义在函数或代码块内,作用域仅在函数或块内,栈上分配。
  • 全局变量:定义在所有函数外部,程序运行期间一直存在。
  • 静态变量:局部静态变量在函数内定义但跨函数调用保持值,全局静态变量作用域限制在声明文件。

6. 全局变量定义在头文件中有什么问题?

将全局变量定义在头文件中可能导致重复定义问题。每个包含该头文件的源文件都会有该变量的定义,导致链接错误。解决方案是使用extern声明全局变量,并在一个源文件中定义它。

7. 内存对齐

内存对齐是指将数据放在内存中特定的边界地址上,以提高内存访问效率。编译器通过填充字节使得数据对齐到适合的边界。常见对齐边界有1、2、4、8字节等。

8. 什么是内存泄露

内存泄露是指程序在堆上分配内存后未能正确释放,导致内存无法被再次使用,最终可能耗尽系统内存。

9. 怎么防止内存泄漏?内存泄漏检测工具的原理?

  • 防止内存泄漏:使用智能指针(如std::unique_ptrstd::shared_ptr),避免手动管理内存。养成良好编码习惯,确保每次new都有对应的delete
  • 内存泄漏检测工具:工具如Valgrind、AddressSanitizer通过监控内存分配和释放操作,记录未释放的内存块,帮助定位内存泄漏点。

10. 智能指针有哪几种?智能指针的实现原理?

  • 智能指针种类
    • std::unique_ptr:独占所有权,不能复制,只能转移所有权。
    • std::shared_ptr:共享所有权,通过引用计数管理。
    • std::weak_ptr:不控制所有权,配合shared_ptr使用,防止循环引用。
  • 实现原理:智能指针类封装了指针操作,提供构造、析构、拷贝、赋值等操作。在析构时自动释放资源,以防止内存泄漏。

11. 智能指针应用举例

例如,在管理动态创建的对象生命周期时,使用std::shared_ptr来确保对象在不再需要时自动删除:

std::shared_ptr<MyClass> p1(new MyClass());
std::shared_ptr<MyClass> p2 = p1; // p1 和 p2 共享所有权

12. 一个 unique_ptr 怎么赋值给另一个 unique_ptr 对象?

unique_ptr不能直接赋值,因为它禁止拷贝。可以使用std::move将所有权从一个unique_ptr转移到另一个:

std::unique_ptr<MyClass> p1(new MyClass());
std::unique_ptr<MyClass> p2 = std::move(p1);

13. 使用智能指针会出现什么问题?怎么解决?

  • 循环引用问题std::shared_ptr可能会导致循环引用,从而无法释放内存。解决方法是使用std::weak_ptr打破循环。
  • 性能开销:智能指针带有额外的开销,如引用计数管理。可以在性能敏感区域谨慎使用。

14. VS检测内存泄漏,定位泄漏代码位置方法

在Visual Studio中,可以通过启用内存泄漏检测功能和使用_CrtDumpMemoryLeaks()函数来定位内存泄漏。通过在程序结束时调用该函数,可以输出所有未释放的内存块信息。

15. 深拷贝与浅拷贝

  • 浅拷贝:只复制对象的指针,不复制实际内容。两个对象共享同一内存块。
  • 深拷贝:复制对象的内容,每个对象都有自己的内存块,互不影响。

16. 虚拟内存

虚拟内存是操作系统提供的一种技术,将程序的虚拟地址空间映射到物理内存或磁盘上。它允许程序使用比实际物理内存更多的地址空间。

17. 语言对比

C++与其他语言对比,可能包括对比C、Python、Java等。需要根据具体情况讨论语言的特点、应用场景和优缺点。

18. C++ 11 新特性

C++11引入了许多新特性,如:

  • auto关键字用于类型推导。
  • nullptr表示空指针。
  • lambda表达式,简化了函数对象。
  • std::thread,标准库中的多线程支持。
  • std::unique_ptrstd::shared_ptr智能指针。

19. C 和 C++ 的区别

  • 面向对象:C++支持类和对象,C不支持。
  • 泛型编程:C++支持模板,C不支持。
  • 异常处理:C++支持异常处理,C通常使用返回值进行错误处理。
  • 内存管理:C++提供了智能指针等自动管理内存工具,C需要手动管理。

20. Python 和 C++ 的区别

  • 语法:Python语法简洁,适合快速开发;C++语法复杂,更接近底层。
  • 性能:C++编译后的程序性能高,适用于性能敏感的领域;Python是解释型语言,运行速度较慢。
  • 内存管理:C++需要手动管理内存,Python通过垃圾回收自动管理内存。

21. 面向对象

面向对象编程(OOP)是一种编程范式,它使用对象和类的概念来设计程序。OOP的核心是封装、继承和多态。

22. 什么是面向对象?面向对象的三大特性

面向对象是一种编程范式,强调将数据和操作数据的函数封装在对象内。三大特性包括:

  • 封装:将数据和方法绑定在一起,对外隐藏实现细节。
  • 继承:允许新类继承现有类的特性和行为。
  • 多态:允许不同类的对象通过相同的接口调用不同的行为。

23. 重

载、重写、隐藏的区别

  • 重载:同一作用域中函数名相同但参数列表不同。
  • 重写:派生类重新定义基类中的虚函数,函数签名相同。
  • 隐藏:派生类中的函数屏蔽了基类中同名函数,不要求签名相同。

24. 如何理解 C++ 是面向对象编程

C++通过类和对象实现面向对象编程的三大特性,允许程序员通过封装、继承和多态创建模块化、可复用的代码。

25. 什么是多态?多态如何实现?

多态是指不同类的对象可以通过相同的接口调用不同的实现。C++中多态通过虚函数实现,基类中声明虚函数,派生类可以重写该函数。

26. 静态多态与动态多态

  • 静态多态:在编译时确定函数调用,如函数重载和模板。
  • 动态多态:在运行时确定函数调用,如虚函数。

27. 类相关

涉及类的设计和使用,包括构造函数、析构函数、拷贝构造函数、赋值运算符等。

28. 什么是虚函数?什么是纯虚函数?

  • 虚函数:基类中声明的可以在派生类中重写的函数,使用virtual关键字声明。
  • 纯虚函数:没有实现的虚函数,必须在派生类中重写,基类不能实例化,使用= 0声明。

29. 虚函数和纯虚函数的区别?

  • 虚函数:基类中有默认实现,可以在派生类中重写。
  • 纯虚函数:基类中没有实现,必须在派生类中实现,通常用于定义接口。

30. 虚函数的实现机制

虚函数通过虚函数表(vtable)实现。每个含有虚函数的类都有一个vtable,存储类中虚函数的地址。对象的vptr指向这个表,通过vptr访问vtable,实现动态绑定。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sagima_sdu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值