0%

面经C++基础知识2

面经 C++ 基础知识

介绍fork函数

创建一个和当前进程映像一样的进程可以通过fork( )系统调用。成功调用fork 会返回一个大于等于0 的数,对于主进程,返回的是子进程的pid,子进程中返回的是0;可以通过if判断来确定是在子进程还是父进程中,然后执行不同的功能,两个进程执行的先后顺序完全由系统调度决定。

1
2
3
#include<sys/types.h>
#inclde<unistd.h>
pid_t fork(void);

友元

友元函数:如果一个函数需要访问一个类的的成员,那么可以将该函数申明为类的友元函数。即在类中增加friend 类型 函数名(形式参数);申明语句,申明位置在 private 或者 public下都一样。一个函数可以同时是多个类的友元函数。

友元类:friend声明在哪个类中就是哪个类的友元类,不是双向的,不能传递。可以使用声明所在类的所有成员变量和函数。

模板

C++是一门强类型语言,所以无法做到像动态语言(python javascript)那样子,编写一段通用的逻辑,可以把任意类型的变量传进去处理。泛型编程弥补了这个缺点。

模板分为函数模板 和 类模板,建立一个通用的规则 在函数调用时才区推导具体的参数类型,因此模板的实例化是在 编译期间确定的而不是链接时确定的,所以不能将模板定义和声明分散到多个文件,这可能会导致在链接期间找不到对应的实例。

深拷贝和浅拷贝

当类中含有动态分配的数据空间时 直接调用 赋值 运算符 难么就是浅拷贝,只能将类中定义的成员变量拷贝过去,而指针指向的动态分配的内存无法拷贝。需要手动定义拷贝构造函数 来完成深拷贝。

C++类中数据成员初始化顺序

  1. 成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关
  2. 如果不使用初始化列表初始化,在构造函数内初始化时,此时与成员变量在构造函数中的位置有关。
  3. 类中 const 成员常量必须在构造函数初始化列表中初始化
  4. 类中static成员变量,只能在类外初始化(同一类的所有实例共享静态成员变量)。

初始化顺序:先静后成员变量、先基后派生

  1. 基类的静态变量或全局变量
  2. 派生类的静态变量或全局变量
  3. 基类的成员变量
  4. 派生类的成员变量

类的大小

sizeof(A) 空类 =1(占位s) class A { virtual Fun(){} }; sizeof(A) =4/8 虚函数指针大小

C++中大端小端的优缺点

大端模式: 低位存在高地址 小端:低位存在低地址;使用 联合体判断,因为联合体存放顺序是所有成员都从低地址开始存放

判定:

1
2
3
4
5
6
7
8
9
10
11
int main() {
union {
int i;
char c;
} u;
u.i = 1;
if(u.c == 1)
cout << "小端" << endl;
else
cout << "大端" << endl;
}

作用:

大端模式:第一个字节一定包含符号位 所以方便判定不同长度数据的符号 小端模式:强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。(直接截断 否则大端模式 还存在错位拷贝)

C++中*和&同时使用是什么意思

*表示传进来的是指针,只能改变指针指向地址的值,不能改变指针本身

int * &p表示既能改变地址中的值,又能改变指针

[i]和.at(i)访问有什么区别

.at有越界检查,如果越界会报错,[]为了效率就没有

fork wait exec函数

select 函数