1. C++ 中 struct 和 class 的区别是什么?
在C++中,struct 和class的主要区别就在于它们的默认访问级别:
-
struct的默认成员访问级别是public。 -
class的默认成员访问级别是private。
2. C++ 中 struct 和 union 的区别?如何使用 union 做优化?
struct和 union二者有以下主要区别:
-
存储方式:
struct中的所有成员变量各自占据独立的内存空间,而union中的所有成员变量共用同一块内存空间,且大小是最大成员的大小。 -
访问方式:
struct的所有成员变量可以同时存在并被访问,而union每次只能有一个成员变量有效,如果在一个成员值改变后访问另一个成员,结果不可预知。 -
用途:
struct一般用于逻辑上关联的不同数据存储,而union通常用于节省内存空间,作为一个优化项使用。例如在嵌入式系统或资源有限的场景中。通过让变量共用内存,可以减少内存消耗。很多底层库为了性能极致,也会使用union,我们如果开发业务层代码,建议直接使用struct,好用且不容易出bug。
3. C++ 中 using 和 typedef 的区别?
using在 C++11 中引|入,using 和 typedef都可以用来为已有的类型定义一个新的名称。最主要的区别在于,using可以用来定义模板别名,而typedef 不能。
- typedef主要用于给类型定义别名,但是它不能用于模板别名。
cpp
typedef unsigned long ulong;
typedef int (*FuncPtr)(double);
2. using可以取代typedef的功能,语法相对简洁。
cpp
using ulong = unsigned long;
using FuncPtr = int (*)(double);
- 对于模版别名,
using显得非常强大且直观。
cpp
template<typename T>
using Vec = std::vector<T>;
总之,更推荐使用 using,尤其是当你处理模版的时候。
4. C++ 中 enum 和 enum class 的区别?
在C++中,enum 和 enum class(也叫做强类型枚举)主要的区别在于作用域和类型安全。
- 作用域:
-
enum:枚举成员是直接进入包含它的作用域(也就是说,在定义枚举后,你可以直接使用枚举成员,而不需要前缀)。 -
enum class:枚举成员只能通过显式地指定它们的枚举类型来访问(即使用枚举名作为前缀,类似于作用域解析)。
- 类型安全:
-
enum:传统枚举类型不安全,枚举成员会隐式转换为整数类型。
-
enum class:强类型枚举是类型安全的,不能隐式转换为其他类型,必须显式转换。
举个例子:
cpp
// 传统枚举
enum Color {
RED,
GREEN,
BLUE
};
// 强类型枚举
enum class ColorClass {
RED,
GREEN,
BLUE
};
// 使用示例
int main() {
// 对于传统枚举
Color c = RED; // 直接访问,不需要前缀
int value = GREEN; // 可能的隐式转换
// 对于强类型枚举
ColorClass cc = ColorClass::RED; // 需要前缀
// int value = ColorClass::GREEN; // 错误,不能隐式转换,需要显式转换
return 0;
}
5. C++ 中 new 和 malloc 的区别?delete 和 free 的区别?
在C++中,new 和malloc 以及 delete 和free 是内存管理的两对主要操作符和函数。它们虽然都有分配和释放内存的功能,但在很多方面都有区别。
1. new VS malloc :
-
new是C++的操作符,而malloc是 C 标准库的函数。 -
new分配内存并调用构造函数 ,而malloc仅仅分配内存,不调用构造函数。 -
new返回一个类型安全的指针,malloc返回而void*,需要显式类型转换。 -
new在分配失败时抛出std::bad_alloc异常,而malloc 返回NULL。
2. delete VS free :
-
delete是 C++ 的操作符,而free是C标准库的函数。 -
delete销毁对象并调用析构函数 ,然后释放内存,而free仅仅释放内存,不调用析构函数。 -
delete必须与new配对使用,而free必须与malloc配对使用。 -
delete和delete[]是不同的,前者用于单一对象,后者用于数组。free没有这种区分。
6. C++ 中类定义中 delete 关键字和 default 关键字的作用?
两者都用于控制类的行为。
1. delete关键字用来禁用某些默认的成员函数。主要的作用就是禁用拷贝构造函数和拷贝赋值运算符,如下例:
cpp
class MyClass
{
public:
MyClass() = default; // 使用默认构造函数
MyClass(const MyClass&) = delete; // 禁用拷贝构造函数
MyClass& operator=(const MyClass&) = delete; // 禁用拷贝赋值运算符
};
- default关键字用于显式地指示编译器为某个成员函数生成默认的实现。它经常用在构造函数、析构函数,以及拷贝构造函数上。
cpp
class MyClass {
public:
MyClass() = default; // 使用默认构造函数
~MyClass() = default; // 使用默认析构函数
MyClass(const MyClass&) = default; // 使用默认拷贝构造函数
MyClass& operator=(const MyClass&) = default; // 使用默认拷贝赋值运算符
};
7. C++ 中 this 指针的作用?
this指针是一个隐含在每一个非静态成员函数中的指针。它指向的是调用成员函数的那个对象的地址。主要作用包括:
-
访问类的成员变量和成员函数,特别是当局部变量与成员变量同名时,用
this指针可以明确的区分出来。 -
链式调用:可以通过返回
*this来支持链式调用。 -
动态绑定:在基类指针或引用调用派生类对象时,利用
this指针可以直观的实现动态绑定。
8. C++ 中 可以使用 delete this吗?
可以使用 delete this,但是必须非常谨慎,因为滥用可能会导致未定义行为。delete this的主要作用是允许对象在其成员函数中自行销毁。但这对程序员的要求很高,你需要明确知道这会产生什么样的影响。
一般建议普通开发者不要使用 delete this,因为日常业务开发中,几乎不需要这样使用。起码笔者十数年的编程生涯中,只见过标准库中这样使用,自己编写业务代码时还没有这样使用过。
9. C++ 中 vector 的原理?resize 和 reverse 的区别是什么? size和 capacity 的区别?
vector是一个动态数组 ,它可以根据需要进行自动伸缩。这里的关键词是动态数组,动态两字很关键。
内部实现上,vector通过一个指向连续内存的指针来管理对应元素,并根据需要动态扩容,分配内存来满足容量需求。
1. resize 和 reserve 的区别:
-
resize(n):调整vector的大小为n。如果n大于当前大小,会向vector末尾添加值初始化的新元素;如果n小于当前大小,会删除超出部分的元素。如果n大于capacity,会自动扩容,满足容量需求。 -
reserve(n):预分配内存,确保vector可以存储n个元素,但不改变vector的当前大小。适用于在已知将要添加大量元素的情况下进行预分配,以避免频繁重新分配内存。
2. size和capacity的区别:
-
size:vector中当前包含的元素数量。上面的resize(n),会改变size大小。 -
capacity:vector当前分配的内存能够容纳的最大元素数量。上面的reserve(n),会改变capacity大小。