mirror of
https://github.com/huihut/interview.git
synced 2024-03-22 13:10:48 +08:00
commit
3e38312302
14
README.md
14
README.md
|
@ -84,14 +84,14 @@ int* const function7(); // 返回一个指向变量的常指针,使用:i
|
||||||
#### 作用
|
#### 作用
|
||||||
|
|
||||||
1. 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在 main 函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。
|
1. 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在 main 函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。
|
||||||
2. 修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内才能使用。在多人开发项目时,为了防止与他人命令函数重名,可以将函数定位为 static。
|
2. 修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内才能使用。在多人开发项目时,为了防止与他人命名空间里的函数重名,可以将函数定位为 static。
|
||||||
3. 修饰成员变量,修饰成员变量使所有的对象只保存一个该变量,而且不需要生成对象就可以访问该成员。
|
3. 修饰成员变量,修饰成员变量使所有的对象只保存一个该变量,而且不需要生成对象就可以访问该成员。
|
||||||
4. 修饰成员函数,修饰成员函数使得不需要生成对象就可以访问该函数,但是在 static 函数内不能访问非静态成员。
|
4. 修饰成员函数,修饰成员函数使得不需要生成对象就可以访问该函数,但是在 static 函数内不能访问非静态成员。
|
||||||
|
|
||||||
### this 指针
|
### this 指针
|
||||||
|
|
||||||
1. `this` 指针是一个隐含于每一个非静态成员函数中的特殊指针。它指向调用该成员函数的那个对象。
|
1. `this` 指针是一个隐含于每一个非静态成员函数中的特殊指针。它指向调用该成员函数的那个对象。
|
||||||
2. 当对一个对象调用成员函数时,编译程序先将对象的地址赋给 `this` 指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含使用 `this` 指针。
|
2. 当对一个对象调用成员函数时,编译程序先将对象的地址赋给 `this` 指针,然后调用成员函数,每次成员函数存取数据成员时,都隐含使用 `this` 指针。
|
||||||
3. 当一个成员函数被调用时,自动向它传递一个隐含的参数,该参数是一个指向这个成员函数所在的对象的指针。
|
3. 当一个成员函数被调用时,自动向它传递一个隐含的参数,该参数是一个指向这个成员函数所在的对象的指针。
|
||||||
4. `this` 指针被隐含地声明为: `ClassName *const this`,这意味着不能给 `this` 指针赋值;在 `ClassName` 类的 `const` 成员函数中,`this` 指针的类型为:`const ClassName* const`,这说明不能对 `this` 指针所指向的这种对象是不可修改的(即不能对这种对象的数据成员进行赋值操作);
|
4. `this` 指针被隐含地声明为: `ClassName *const this`,这意味着不能给 `this` 指针赋值;在 `ClassName` 类的 `const` 成员函数中,`this` 指针的类型为:`const ClassName* const`,这说明不能对 `this` 指针所指向的这种对象是不可修改的(即不能对这种对象的数据成员进行赋值操作);
|
||||||
5. `this` 并不是一个常规变量,而是个右值,所以不能取得 `this` 的地址(不能 `&this`)。
|
5. `this` 并不是一个常规变量,而是个右值,所以不能取得 `this` 的地址(不能 `&this`)。
|
||||||
|
@ -283,7 +283,7 @@ Bit mode: 2; // mode 占 2 位
|
||||||
### extern "C"
|
### extern "C"
|
||||||
|
|
||||||
* 被 extern 限定的函数或变量是 extern 类型的
|
* 被 extern 限定的函数或变量是 extern 类型的
|
||||||
* 被 `extern "C"` 修饰的变量和函数是按照 C 语言方式编译和连接的
|
* 被 `extern "C"` 修饰的变量和函数是按照 C 语言方式编译和链接的
|
||||||
|
|
||||||
`extern "C"` 的作用是让 C++ 编译器将 `extern "C"` 声明的代码当作 C 语言代码处理,可以避免 C++ 因符号修饰导致代码不能和C语言库中的符号进行链接的问题。
|
`extern "C"` 的作用是让 C++ 编译器将 `extern "C"` 声明的代码当作 C 语言代码处理,可以避免 C++ 因符号修饰导致代码不能和C语言库中的符号进行链接的问题。
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ using namespace_name name;
|
||||||
|
|
||||||
#### 尽量少使用 `using 指示` 污染命名空间
|
#### 尽量少使用 `using 指示` 污染命名空间
|
||||||
|
|
||||||
> 一般说来,使用 using 命令比使用 using 编译命令更安全,这是由于它**只导入了制定的名称**。如果该名称与局部名称发生冲突,编译器将**发出指示**。using编译命令导入所有的名称,包括可能并不需要的名称。如果与局部名称发生冲突,则**局部名称将覆盖名称空间版本**,而编译器**并不会发出警告**。另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确知道添加了哪些名称。
|
> 一般说来,使用 using 命令比使用 using 编译命令更安全,这是由于它**只导入了指定的名称**。如果该名称与局部名称发生冲突,编译器将**发出指示**。using编译命令导入所有的名称,包括可能并不需要的名称。如果与局部名称发生冲突,则**局部名称将覆盖名称空间版本**,而编译器**并不会发出警告**。另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确知道添加了哪些名称。
|
||||||
|
|
||||||
<details><summary>using 使用</summary>
|
<details><summary>using 使用</summary>
|
||||||
|
|
||||||
|
@ -672,7 +672,7 @@ auto fcn2(It beg, It end) -> typename remove_reference<decltype(*beg)>::type
|
||||||
|
|
||||||
### initializer_list 列表初始化
|
### initializer_list 列表初始化
|
||||||
|
|
||||||
用花括号初始化器列表列表初始化一个对象,其中对应构造函数接受一个 `std::initializer_list` 参数.
|
用花括号初始化器列表初始化一个对象,其中对应构造函数接受一个 `std::initializer_list` 参数.
|
||||||
|
|
||||||
<details><summary>initializer_list 使用</summary>
|
<details><summary>initializer_list 使用</summary>
|
||||||
|
|
||||||
|
@ -911,7 +911,7 @@ virtual int A() = 0;
|
||||||
* 接口类:仅含有纯虚函数的抽象类
|
* 接口类:仅含有纯虚函数的抽象类
|
||||||
* 聚合类:用户可以直接访问其成员,并且具有特殊的初始化语法形式。满足如下特点:
|
* 聚合类:用户可以直接访问其成员,并且具有特殊的初始化语法形式。满足如下特点:
|
||||||
* 所有成员都是 public
|
* 所有成员都是 public
|
||||||
* 没有有定于任何构造函数
|
* 没有定义任何构造函数
|
||||||
* 没有类内初始化
|
* 没有类内初始化
|
||||||
* 没有基类,也没有 virtual 函数
|
* 没有基类,也没有 virtual 函数
|
||||||
|
|
||||||
|
@ -948,7 +948,7 @@ p = nullptr;
|
||||||
|
|
||||||
#### new、delete
|
#### new、delete
|
||||||
|
|
||||||
1. new / new[]:完成两件事,先底层调用 malloc 分了配内存,然后调用构造函数(创建对象)。
|
1. new / new[]:完成两件事,先底层调用 malloc 分配了内存,然后调用构造函数(创建对象)。
|
||||||
2. delete/delete[]:也完成两件事,先调用析构函数(清理资源),然后底层调用 free 释放空间。
|
2. delete/delete[]:也完成两件事,先调用析构函数(清理资源),然后底层调用 free 释放空间。
|
||||||
3. new 在申请内存时会自动计算所需字节数,而 malloc 则需我们自己输入申请内存空间的字节数。
|
3. new 在申请内存时会自动计算所需字节数,而 malloc 则需我们自己输入申请内存空间的字节数。
|
||||||
|
|
||||||
|
|
|
@ -100,14 +100,14 @@ int* const function7(); // 返回一个指向变量的常指针,使用:i
|
||||||
#### 作用
|
#### 作用
|
||||||
|
|
||||||
1. 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在 main 函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。
|
1. 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在 main 函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。
|
||||||
2. 修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内才能使用。在多人开发项目时,为了防止与他人命令函数重名,可以将函数定位为 static。
|
2. 修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内才能使用。在多人开发项目时,为了防止与他人命名空间里的函数重名,可以将函数定位为 static。
|
||||||
3. 修饰成员变量,修饰成员变量使所有的对象只保存一个该变量,而且不需要生成对象就可以访问该成员。
|
3. 修饰成员变量,修饰成员变量使所有的对象只保存一个该变量,而且不需要生成对象就可以访问该成员。
|
||||||
4. 修饰成员函数,修饰成员函数使得不需要生成对象就可以访问该函数,但是在 static 函数内不能访问非静态成员。
|
4. 修饰成员函数,修饰成员函数使得不需要生成对象就可以访问该函数,但是在 static 函数内不能访问非静态成员。
|
||||||
|
|
||||||
### this 指针
|
### this 指针
|
||||||
|
|
||||||
1. `this` 指针是一个隐含于每一个非静态成员函数中的特殊指针。它指向调用该成员函数的那个对象。
|
1. `this` 指针是一个隐含于每一个非静态成员函数中的特殊指针。它指向调用该成员函数的那个对象。
|
||||||
2. 当对一个对象调用成员函数时,编译程序先将对象的地址赋给 `this` 指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含使用 `this` 指针。
|
2. 当对一个对象调用成员函数时,编译程序先将对象的地址赋给 `this` 指针,然后调用成员函数,每次成员函数存取数据成员时,都隐式使用 `this` 指针。
|
||||||
3. 当一个成员函数被调用时,自动向它传递一个隐含的参数,该参数是一个指向这个成员函数所在的对象的指针。
|
3. 当一个成员函数被调用时,自动向它传递一个隐含的参数,该参数是一个指向这个成员函数所在的对象的指针。
|
||||||
4. `this` 指针被隐含地声明为: `ClassName *const this`,这意味着不能给 `this` 指针赋值;在 `ClassName` 类的 `const` 成员函数中,`this` 指针的类型为:`const ClassName* const`,这说明不能对 `this` 指针所指向的这种对象是不可修改的(即不能对这种对象的数据成员进行赋值操作);
|
4. `this` 指针被隐含地声明为: `ClassName *const this`,这意味着不能给 `this` 指针赋值;在 `ClassName` 类的 `const` 成员函数中,`this` 指针的类型为:`const ClassName* const`,这说明不能对 `this` 指针所指向的这种对象是不可修改的(即不能对这种对象的数据成员进行赋值操作);
|
||||||
5. `this` 并不是一个常规变量,而是个右值,所以不能取得 `this` 的地址(不能 `&this`)。
|
5. `this` 并不是一个常规变量,而是个右值,所以不能取得 `this` 的地址(不能 `&this`)。
|
||||||
|
@ -299,7 +299,7 @@ Bit mode: 2; // mode 占 2 位
|
||||||
### extern "C"
|
### extern "C"
|
||||||
|
|
||||||
* 被 extern 限定的函数或变量是 extern 类型的
|
* 被 extern 限定的函数或变量是 extern 类型的
|
||||||
* 被 `extern "C"` 修饰的变量和函数是按照 C 语言方式编译和连接的
|
* 被 `extern "C"` 修饰的变量和函数是按照 C 语言方式编译和链接的
|
||||||
|
|
||||||
`extern "C"` 的作用是让 C++ 编译器将 `extern "C"` 声明的代码当作 C 语言代码处理,可以避免 C++ 因符号修饰导致代码不能和C语言库中的符号进行链接的问题。
|
`extern "C"` 的作用是让 C++ 编译器将 `extern "C"` 声明的代码当作 C 语言代码处理,可以避免 C++ 因符号修饰导致代码不能和C语言库中的符号进行链接的问题。
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ using namespace_name name;
|
||||||
|
|
||||||
#### 尽量少使用 `using 指示` 污染命名空间
|
#### 尽量少使用 `using 指示` 污染命名空间
|
||||||
|
|
||||||
> 一般说来,使用 using 命令比使用 using 编译命令更安全,这是由于它**只导入了制定的名称**。如果该名称与局部名称发生冲突,编译器将**发出指示**。using编译命令导入所有的名称,包括可能并不需要的名称。如果与局部名称发生冲突,则**局部名称将覆盖名称空间版本**,而编译器**并不会发出警告**。另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确知道添加了哪些名称。
|
> 一般说来,使用 using 命令比使用 using 编译命令更安全,这是由于它**只导入了指定的名称**。如果该名称与局部名称发生冲突,编译器将**发出指示**。using编译命令导入所有的名称,包括可能并不需要的名称。如果与局部名称发生冲突,则**局部名称将覆盖名称空间版本**,而编译器**并不会发出警告**。另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确知道添加了哪些名称。
|
||||||
|
|
||||||
<details><summary>using 使用</summary>
|
<details><summary>using 使用</summary>
|
||||||
|
|
||||||
|
@ -688,7 +688,7 @@ auto fcn2(It beg, It end) -> typename remove_reference<decltype(*beg)>::type
|
||||||
|
|
||||||
### initializer_list 列表初始化
|
### initializer_list 列表初始化
|
||||||
|
|
||||||
用花括号初始化器列表列表初始化一个对象,其中对应构造函数接受一个 `std::initializer_list` 参数.
|
用花括号初始化器列表初始化一个对象,其中对应构造函数接受一个 `std::initializer_list` 参数.
|
||||||
|
|
||||||
<details><summary>initializer_list 使用</summary>
|
<details><summary>initializer_list 使用</summary>
|
||||||
|
|
||||||
|
@ -927,7 +927,7 @@ virtual int A() = 0;
|
||||||
* 接口类:仅含有纯虚函数的抽象类
|
* 接口类:仅含有纯虚函数的抽象类
|
||||||
* 聚合类:用户可以直接访问其成员,并且具有特殊的初始化语法形式。满足如下特点:
|
* 聚合类:用户可以直接访问其成员,并且具有特殊的初始化语法形式。满足如下特点:
|
||||||
* 所有成员都是 public
|
* 所有成员都是 public
|
||||||
* 没有有定于任何构造函数
|
* 没有定义任何构造函数
|
||||||
* 没有类内初始化
|
* 没有类内初始化
|
||||||
* 没有基类,也没有 virtual 函数
|
* 没有基类,也没有 virtual 函数
|
||||||
|
|
||||||
|
@ -964,7 +964,7 @@ p = nullptr;
|
||||||
|
|
||||||
#### new、delete
|
#### new、delete
|
||||||
|
|
||||||
1. new / new[]:完成两件事,先底层调用 malloc 分了配内存,然后调用构造函数(创建对象)。
|
1. new / new[]:完成两件事,先底层调用 malloc 分配了内存,然后调用构造函数(创建对象)。
|
||||||
2. delete/delete[]:也完成两件事,先调用析构函数(清理资源),然后底层调用 free 释放空间。
|
2. delete/delete[]:也完成两件事,先调用析构函数(清理资源),然后底层调用 free 释放空间。
|
||||||
3. new 在申请内存时会自动计算所需字节数,而 malloc 则需我们自己输入申请内存空间的字节数。
|
3. new 在申请内存时会自动计算所需字节数,而 malloc 则需我们自己输入申请内存空间的字节数。
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user