C++面试题知识点总结
1. 内联函数
类内定义的成员函数将自动成为内联函数,一般将短小的成员函数作为内联函数;类外定义的成员函数若要作为内联函数,仅需在返回类型前增加关键字inline;
类外定义的成员函数的格式: 返回类型 类名::函数名(参数列表)
优势:inline是用空间换取时间,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么就没必要去定义内联。所以,如果函数体代码过长、函数体有循环语句、if语句、switch语句、递归时,不宜用内联。
2. 友元函数
类的非成员函数不能直接访问类的私有数据成员,但友元函数可以,即它的访问权限与成员函数相同,但其不能用成员运算符来访问;
创建友元函数:将函数原型放入类声明中,并在原型前加入关键字friend;在类外定义不需要在函数名前指定类作用域运算符;
3. 函数重载
使用户能够定义多个名称相同但特征标(参数列表)不同的函数;
将此概念继续应用在运算符上,可重载运算符;operator[ ] ()函数将重载[ ]运算符。
4. map方法
map是STL的一個容器,以模板的方式实现,所以可以存储任意类型的变量。Map内部以二叉链表的形式存储各个变量,自建了一棵二叉树。其类似于Python中的字典数据结构。
[code] map<int, string> map_data;//变量声明 map<int, string> map_data = { { 1, "yu" },{ 2, "yu" } };//变量初始化
5. xml即可扩展标记语言
xml是互联网数据传输的重要工具,它可以跨平台进行数据交互,它可以跨操作系统,也可以跨编程语言的平台,不受编程语言和操作系统的限制,可以说它是一个拥有互联网最高级别通行证的数据携带者。
6. 文件输出的步骤
a.#include <fstream>
b.创建一个ofstream对象;
c.将对象与文件关联起来,使用open()方法;
d.类似使用cout使用ofstream对象;
读取文件的步骤:
a.#include <fstream>
b.创建一个ifstream对象;
c.将对象与文件关联起来,使用open()方法;
d.类似使用cin使用ifstream对象;
e.#include<cstdlib> 使用is_open()判断文件是否成功打开;
使用good()方法判断读入数据是否发生错误;
使用eof()方法判断是否到达文件尾(EOF);
使用fail()方法判断EOF类型是否匹配;
7. 析构函数
在类对象过期时自动调用析构函数,用于完成释放对象内存。类内函数原型声明,类外定义
[code] Stock::~Stock() { }
8. 派生类
派生类需要添加自己的构造函数、析构函数;可根据需要额外添加数据成员和成员函数;
9. 访问控制:protected
因为子类不能直接访问基类中的私有数据成员,需要通过基类的方法才可以访问。此时,可以在基类中定义protected部分中的类成员,使得子类可以直接访问此基类中的数据成员。其在基类中,与private部分中的数据成员作用一样。
10. 多维数组的表示
[code] int a[][2] = { { 1,2},{ 3,4 } }; //必须指定除第一维以外的所有维度 a;//二维数组的首地址 *(a);//第一行数组的首地址 *(a+ 1);//第二行数组的首地址 *(a+ 1) + 1;//第二行第二个元素的地址 *(*(a+ 1) + 1);//第二行第二个元素的值 (*p)[1];//第一行第二个元素的值,p是二级指针
11. 各数据类型的占用字节
[code]Char 1; short 2; int 2/4(32位机器/8); float 4; long 4; double 8; longdouble 8;
12. 类占用字节
a.类占用字节只与数据成员占用字节和虚函数指针占用字节有关,而与成员函数和静态数据成员无关;
b.虚函数由于要维护一个虚函数表,所以需占用一个指针,也就是4个字节;
c.指针数据成员占用4个字节;
d.类的总大小遵守对齐规则;类或者结构体的自身对齐值是其成员中占用字节最大的那个;数据成员自身对齐值是其数据类型占用字节;
e.共用体占用字节是对齐大小的整数倍,且不能小于最大成员占用字节数
f.枚举型变量可以看做是整型,占用4个字节
12. break、continue
Break:仅使用于循环体和switch语句中,应用在循环体中来跳出循环;应用在switch语句中,使程序仅执行特定部分代码。
Continue:使程序跳过当前循环过程中的剩余代码,执行下个循环。
13. C语言中的字符常量和转义字符常量
字符常量:单引号括起来的字符, ‘a’
转义字符常量: ‘\n’换行 ‘\b’退格 ‘\ddd’转任意字符为三位八进制数
‘\xhh’转任意字符为两位十六进制数 ‘\0’空值
14. new delete malloc free关系
malloc free是C++/C语言的标准库函数;new delete是C++语言的运算符;它们都可用于申请动态内存和释放内存。与new对应的delete会调用对象的析构函数,而与malloc对应的free只会释放内存。
[code] int *pt = newint; delete pt; int *arr = newint[3]; delete[] arr; int node = (int *)malloc(sizeof(int)); free(node);
15. C++面向对象的特点
封装(代码模块化)、多态(接口重用,派生类中重新定义基类的方法,通过虚函数实现)、继承(扩展已有的代码)
多态:方法的行为取决于调用该方法的对象,即此对象可具有多种形态。通过虚函数或者纯虚函数实现。
如果没有使用virtual关键字,则实例对象方法的行为取决于引用或指针对象的方法;
如果使用virtual关键字,则实例对象方法的行为取决于引用或指针指向的对象的方法。
[code] school sch;//基类 person per;//派生类 school &act1 = sch;//调用school::get_data() school &act2 = per;//调用school::get_data() 未使用virtual school &act1 = sch;//调用school::get_data() school &act2 = per;//调用person::get_data()使用virtual
16. 子类的构造函数和析构函数的调用顺序
定义一个对象时,先调用基类的构造函数,再调用子类的构造函数;析构时,先调用子类的析构函数,再调用基类的析构函数。
17. 虚函数、纯虚函数
在基类中的成员函数前加关键字virtual,即定义其为虚函数,则可在子类中重新定义基类方法。
纯虚函数声明的结尾处增加 =0,在基类中通过使用纯虚函数定义未实现的函数,用于在子类中对其进行定义。包含纯虚函数的类被称作抽象类,只能当做为派生其他类的基类,不能创建该类的对象。
特点:a.该基类只能被继承,不能被实例化;b.必须在派生类中实现此方法。
18. struct 和 union的区别
a. 它们都是有不同的数据类型成员组成;
b. Union中所有成员公用一块地址空间,而struct中不同成员占用不同的内存空间。
19. Const与#define的区别
Const使用场所:定义变量、修饰函数入口参数、修饰函数返回值类型
Const常量可定义数据的类型,而宏定义是没有数据类型的。编译器可对const定义的常量进行类型安全检查,而宏定义只是对字符的替换,没有类型安全检查,所以应该更多的去使用const.
20.指针和引用的区别
指针是一个新的变量,此变量存储另一个变量的地址,通过此变量来修改另一变量;
引用只是定义了另一个变量的别名,指向的还是同一个变量。
[code]int a = 1; int &b = a; cout <<"引用:"<< b << endl;
21.浅拷贝和深拷贝
浅拷贝指的是在复制对象成员时,仅对数据成员进行简单的赋值;
深拷贝指的是当对象中存在动态成员时,不能直接进行赋值,而需重新为其分配内存空间。
[code] //深拷贝构造函数 Rect(constRect &r) { width= r.width; height= r.height; //为新对象重新分配动态内存空间 p= newint; *p= *(r.p); } //浅拷贝构造函数 Rect(const Rect &r) { width= r.width; height= r.height; }
22. 字符数组和指针字符的区别
[code]char words[] = "Deep Learing is very hard"; cout<< words << endl;
打印数组名,输出的是字符数组,但数组名作为入口参数时,则指的是第一个字符的地址。
[code]char *words = "Deep Learing is very hard"; cout << words << endl;
打印指针变量,输出的是字符串,指针变量作为入口参数时,指的是字符串的地址。
23. 线程和进程的区别
a.进程是资源分配的基本单元,而线程是系统独立调度和分配CPU运行的基本单元
b.同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程。
c.进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
d.线程是轻量级的进程,它的创建和销毁所需要的时间比进程小很多
e.线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源
24.线程的并发和并行
并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状态。
并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行。
25. 什么是多态
函数的多种形态,多态是基于继承和虚函数来实现的,声明基类对象,若未将基类成员函数声明为虚函数,则根据基类对象指向的指针类型来选择,即基类成员函数;若将基类成员函数声明为虚函数,则根据基类对象指向的对象类型来选择,即派生类成员函数。依此机制,实现了函数的多种选择方式,所以叫多态。
26. 派生类不一定非得实现基类的纯虚函数
含有纯虚函数的类是抽象类,继承此类的为派生类。若派生类实现了此纯虚函数,则此派生类可以被实例化;若派生类未实现此纯虚函数,则此派生类仍为抽象类,不能被实例化。
27. C++数据的三种内存管理
a. 自动存储区(栈)
存储局部变量,函数运行结束,则释放内存
b. 静态存储区
存储全局变量和静态变量,代码运行结束,则释放内存
c. 动态存储区(堆)
new关键则申请的内存,需手动申请,手动释放内存
28. STL vector内存扩容与释放
Vector是动态数组,有一个指针指向一片连续的内存空间,但此内存空间并不是无限大,当puch_bach()元素超过分配内存的容量时,则扩容此内存,先将元数据拷贝过去,然后释放原内存。
VS以1.5倍内存扩容:1*1.5=2(只有第一次扩容向上取整) 2*1.5=3 3*1.5=4(向下取整) 4*1.5=6 …
29. 静态联编和动态联编
静态联编:在编译阶段将函数实现和函数调用联系起来
动态联编:在执行阶段将函数实现和函数调用联系起来
30. 静态成员函数和非静态成员函数的区别
类的静态成员,在类加载的时候就会分配内存,可以通过类名(::)、对象名直接访问(.),且不传递this指针;另外,同一类的所有实例对象共享静态数据成员,可以节省内存。
类的非静态成员,在类创建实例对象时才会分配内存,只可以通过类对象名(. ->)访问.
31. #include 双引号和尖括号的区别
双引号:表示编译器先在用户的工作目录下寻找头文件,如果搜索不到,则到系统默认目录下寻找头文件,所以双引号一般用于包含自己编写的头文件。
尖括号:表示编译器只在系统默认目录或尖括号包含的目录下寻找头文件,并不去用户的工作目录下寻找,所以尖括号一般用于包括标准库文件。
阅读更多
- C++ 面试知识点总结
- 最近看的一些关于数据结构和C++的面试知识点总结
- C/C++面试知识点总结(二)
- C++及数据结构笔试面试常见知识点总结
- C++面试知识点总结
- C/C++面试知识点总结
- C++及数据结构笔试面试常见知识点总结
- C++面试知识点总结
- C/C++面试知识点总结(一)
- 面试知识点总结之c++基础(一)
- C++笔试面试真题回顾与知识点总结
- 面试知识点总结之c++基础(二)
- C++ 面试知识点总结
- C-C++面试知识点总结(三)
- 常见C++面试题及基本知识点总结(一)
- C++中标准库类型vector易忘知识点总结
- 面试笔试总结(一)之 C++基础
- C/C++小知识点总结
- 数据结构(c++版)(第2版)第一章:绪论的知识点总结图,制作者:信管1134-28
- [置顶]那些不能遗忘的知识点回顾——C/C++系列(笔试面试高频题)