1.基础知识
1.关键字
目录
[1. C/C++ 中关键字 static 的作用?](#1. C/C++ 中关键字 static 的作用?)
[2. C/C++ 中关键字 const 的作用?](#2. C/C++ 中关键字 const 的作用?)
[3. C/C++ 中关键字 extern 的作用?](#3. C/C++ 中关键字 extern 的作用?)
[2. 其他常见基础知识](#2. 其他常见基础知识)
[1. 什么是无锁队列?](#1. 什么是无锁队列?)
[1. sizeof 和 strlen 的区别](#1. sizeof 和 strlen 的区别)
[2. malloc/new 的区别?](#2. malloc/new 的区别?)
[3. 指针和引用的区别](#3. 指针和引用的区别)
[4. 静态库,动态库区别?](#4. 静态库,动态库区别?)
[4. 面向对象](#4. 面向对象)
[1. 面向对象三大特性](#1. 面向对象三大特性)
[2. struct和class的区别,](#2. struct和class的区别,)
[3. C++ 空类默认六大成员函数](#3. C++ 空类默认六大成员函数)
[4. 什么是多态?如何实现多态?](#4. 什么是多态?如何实现多态?)
[5. 什么是函数重载?重写?](#5. 什么是函数重载?重写?)
[6. 什么是虚函数?什么是纯虚函数?](#6. 什么是虚函数?什么是纯虚函数?)
[7. 什么是抽象类?](#7. 什么是抽象类?)
[8. 什么是虚函数表?虚指针?](#8. 什么是虚函数表?虚指针?)
[9. 为什么父类指针可以调用子类方法?](#9. 为什么父类指针可以调用子类方法?)
[10. 构造函数能否为虚函数?](#10. 构造函数能否为虚函数?)
[11. 什么是菱形继承?会出现什么问题?怎么解决?](#11. 什么是菱形继承?会出现什么问题?怎么解决?)
1. 关键字 static 的作用?
a. 修饰局部变量,令它的生命周期延长到整个程序结束。但作用域仍限于函数内部。
b. 修饰全局变量/函数。令其仅在当前文件可见,其他文件无法访问。
c. C++中用法,
修饰成员变量,所有对象共享一份数据,不属于单个对象。
修饰成员函数,只能访问静态成员变量,无this指针,可直接通过类名调用。
2. 关键字 const 的作用?
a. 修饰普通变量。变量值不可修改。
b. 修饰指针。
const int *p 指针指向的值只读,指针本身可修改。
int *const p 指针本身只读,指向的值可修改。
const int *const p 指针本身只读,指向的值也只读。
c. 修饰函数参数/返回值。防止函数内部误修改传入的变量,让返回值不可被修改。
d. C++中修饰成员函数,函数内不能修改任何成员变量。
还可以修改对象,对象就只能调用常成员函数。
3. 关键字 extern 的作用?
a. 生命外部全局变量 b. 声明外部函数 c. extern "C" 告诉编译器按C规则编译
4. 关键字final 的作用?
- 修饰类 :该类不能被继承
- 修饰虚函数 :该函数不能被重写
5. 关键字override的作用
- 修饰子类重写的虚函数
- 作用:强制编译器检查,确保函数名、参数完全匹配父类虚函数
- 写错会直接报错,避免 BUG
6. 关键字 volatile 的作用?
禁止编译器优化,直接读取内存原值
2. 其他常见基础知识
1. 什么是无锁队列?
无锁队列(Lock-Free Queue)是一种多线程安全的队列,但不使用互斥锁(mutex)/ 自旋锁,而是靠CPU 原子指令(最核心是CAS:Compare-And-Swap)来保证并发正确。
3.常见辨析
1. sizeof 和 strlen 的区别
a. sizeof 是操作符;strlen是库函数
b. sizeof 是计算内存总字节数,不关心'\0'. strlen 是计算字符串有效字符个数,遇到'\0'停止。
2. malloc/new 的区别?
- malloc :C 语言的库函数 ,只负责分配裸内存,不做初始化,不调用构造函数。失败会返回NULL, 因此需要判断返回值。
- new :C++ 的关键字 / 运算符 ,分配内存 + 自动调用构造函数(初始化对象),是类型安全的。失败会抛出异常,因此需要做异常处理。
3. 指针和引用的区别
- 指针是变量地址,引用是变量别名
- 指针占用内存,引用无独立存储空间
- 指针可空、可改指向,引用初始化绑定后不可变更
- 存在多级指针,不存在多级引用
- 传参指针可传空值,引用使用更简洁安全
4. 静态库,动态库区别?
-
静态库(.a/.lib) 编译时直接打包进可执行文件 ,运行时不需要库文件。
-
动态库(.so/.dll) 编译时只记录引用 ,不打包进去,运行时必须带上库文件才能跑。
5. delete和delete\[\]的区别
new对应delete, 释放单个对象。new\[\]对应 delete\[\], 用于释放数组对象。
6. 引用和值传递的区别?
值传递,本质是传递的复制副本。因此,在函数里修改值,本体不受影响。
引用的话,形参是实参的别名,共用同一个内存地址,因此,在函数里修改值,本体受影响。
4. 面向对象
1. 面向对象三大特性
-
封装将属性和方法打包隐藏,对外仅暴露可用接口,屏蔽内部实现细节,保障数据安全。
-
继承子类复用父类代码与属性,可扩展新增功能,减少冗余代码。
-
多态同一行为作用于不同对象,呈现不同执行效果,分为编译多态、运行多态。
2. struct和class的区别,
主要是访问权限和继承权限不同。struct 默认是public, class 默认是private.
C++中定义的变量默认是strcut还是class?
C++中变量既不是struct也不是class, int/float 等这些都是基础数据类型。
3. C++ 空类默认六大成员函数
定义空类 class A{};,编译器会自动合成6 个默认成员函数
-
默认构造函数 可重载,不可为虚函数
-
默认析构函数 不可重载,可以为虚函数
-
拷贝构造函数
-
拷贝赋值运算符
-
移动构造函数
-
移动赋值运算符
4. 什么是多态?如何实现多态?
父类指针 / 引用 ,指向子类对象,调用虚函数时,执行子类重写的逻辑
口诀:一个接口,多种实现。
- 静态多态:重载
- 运行多态:虚函数 + 重写
5. 什么是函数重载?重写?
重载(overload):同一个类里,函数名相同,参数列表不同
重写/覆盖(override):子类重新写一个和父类返回值、函数名、参数完全一致的函数
6. 什么是虚函数?什么是纯虚函数?
在基类中被virtual 修饰的就是虚函数: virtual void func();
没有函数实现,只为预留接口的,比如 virtual void func() = 0; 就是纯虚函数。
7. 什么是抽象类?
包含纯虚函数的就是抽象类。抽象类不能实例化,无法创建对象。子类必须全部重写所有纯虚函数,否则子类也变为抽象类。
8. 什么是虚函数表?虚指针?
虚函数表:存有当前类所有虚函数地址的一张静态地址数组。
虚表存放在代码段,不属于对象内存。
一个类只会生成唯一一个虚表,所有对象共用这个虚表。
虚指针:每个含有虚函数的类,其对象内部都会自动暗藏一个虚指针,这个指针指向当前的虚函数表。
9. 为什么父类指针可以调用子类方法?
父类指针虽然类型为基类,但是指向的是子类对象。子类对象内部的虚指针会指向子类虚函数表,从而找到并调用子类重写后的成员函数。
10. 构造函数能否为虚函数?
<不能。虚函数依赖虚表。虚表在构造结束后才初始化。因此,在构造对象之前,还没有虚表,因而,也就没有虚函数。>
构造函数不能是虚函数。而且不能在构造函数中调用虚函数,因为那样实际执行的是父类的对应函数,因为自己还没有构造好。
析构函数可以是虚函数,而且,在一个复杂类结构中,这往往是必须的。
析构函数也可以是纯虚函数,但纯虚析构函数必须有定义体,因为析构函数的调用是在子类中隐含的。
11. 什么是菱形继承?会出现什么问题?怎么解决?
菱形继承:一个基类,被两个派生类公有继承,这两个派生类又共同派生出一个子类。
- 数据冗余:孙子类会保留两份基类成员,占用多余内存
- 二义性:直接访问基类成员,编译器分不清调用哪一份,编译报错
使用虚继承,继承时加关键字 virtual