FAQ CPP
根据笔记整理,偏基础概念,
配合右下角大纲视图食用更佳,
具体关键词自行搜索资料展开。
注:没有逻辑顺序,仅供参考。
i++和++i有什么区别
都是自增运算,区别:
- i++返回原始值:背后用到const返回old_value
- ++i返回自增值:背后引用传值直接修改实参
vector添加元素的方法
两种:
- emplace_back: 直接创建,高效率,C++11新特性
- push_back: 先创建再拷贝/移动,效率低但向前兼容
二叉树翻转
要点:使用recursive遍历所有节点
struct Node
{
char *name;
Node *left;
Node *right;
}
Node Invert(Node &tree)
{
// set end condition
if(NULL==tree) return NULL;
tree->left = Invert(tree->left);
tree->right = Invert(tree->right);
// do swap
Node *tmp = tree->left;
tree->left = tree->right;
tree->right = tmp;
return tree;
}
文件流相关
fstream包含读ifstream和写ofstream
常指针区分
const *
:const修饰被指变量,指向常量的指针
* const
:const修饰指针本身,指向固定的地址
静态成员函数
static成员函数不属于任何对象或实例,因此声明virtual也没有意义。
说说STL容器
主要有vector, queue, stack, priority_queue, deque(双端), string, set, multiset(允许重复), bitset, map(与pair的区别在于唯一映射)
简述C++从文本到程序的过程
预编译 -> 编译 -> 汇编 -> 链接
2.0新特性
auto, unllptr, shared_ptr, {1,2,3}init, &&A, atomic, array(STL), tuple(STL)
array和vector区别
array需要指定长度而vector不用(动态扩展)
class和struct成员区别
class默认private而struct默认public
atomic作用
atomic 原子类,用于不同线程之间同步内存访问,如std::atomic<bool> std::atomic<char>
static作用
- 保持函数局部变量值,下次调用仍继承上次值
- 限制全局变量作用域在声明文件内,静态函数只能在声明文件可见
- 类静态成员函数仅生成一个副本且所有对象共享,类的静态函数不接受this指针
const作用
- 修饰变量,只读
- 修饰指针,左右含义不同
- 常量引用,高效安全
- 类成员函数
常量定义
通过const定于的常量必须初始化,保存位置
局部:stack,全局:memory(符号表)
变量长度
sizeof是运算符,strlen是函数
引用与指针
引用的本质实现为指针(语法糖),区别在于:
- 不存在空引用,但存在空指针
- 不可修改引用在初始化后
- 引用必须创建时初始化
- 指针可以多级,引用只有一级
智能指针
- shared_ptr:允许多个指针指向同一对象,指针增加对象引用计数,引用数归零的对象自动析构;
- unique_ptr:独占所指对象,销毁指针时对象随之销毁,与早期auto_ptr类似;
- weak_ptr:弱引用,不控制所指对象生命周期,不增加引用计数。
内联函数
为解决效率问题,编译直接展开而非调用,因此不能太复杂
成员函数类中定义默认内联,类外定义默认普通。
重载
同一作用域中声明功能类似的同名函数,形参(类型、数量、顺序)不同
模板
泛型编程概念,包含函数模板和类模板
处理返回值
函数return前生成一个临时变量存入内存,调用程序访问地址,获取返回值
虚函数与内联
虚函数可以是内联函数,但虚函数表现出多态时不能内联
构造/析构函数重载
ctor(构造函数)可以重载(多个,是否带参数)
dtor(析构函数)不能重载(唯一,不接受参数)
派生类与基类
派生类中定义基类同名函数,基类非虚,此时基类函数被隐藏。
类访问修饰符
protected与private区别在于子类可否访问
copy ctor, move ctor, friend func(可访问任何成员,包括private)
有关this指针
类的成员函数均隐式传入this指针,friend和static无,且friend不是类的成员
类的虚析构函数
只有当一个类作为基类被继承时才能为其设计虚析构函数,原因:
- 基类指针指向new子类,释放基类指针可以释放子类空间,防止内存泄漏;
- 默认dtor非虚,因为虚函数需要占用额外虚函数表与虚表指针,开销内存。
static与virtual函数
- static编译时已经确定运行时机,virtual运行时动态绑定;
- virtual使用vtable机制,调用将增加内存开销。
面向对象OOP特征
封装、继承、多态
特殊的堆栈类
heap only:dtor设为private
stack only: new/delete operator设为private
空类内容
空类包含ctor, copy ctor, dtor, operator=, operator&, const operator&
类的大小
sizeof class 空类返回1;普通成员函数不参与sizeof统计;虚函数+4bytes
static成员不影响类大小,编译器放在程序数据段中;普通继承sizeof相加
动态内存
C++: new/delete 自动申请大小,不释放会泄露
C: malloc/free 需要指定大小,不会调用ctor和dtor
堆栈区别
内存 | 申请分配 | 效率 | 扩展方向 | 举例 |
---|---|---|---|---|
stack | 自动 | 高 | 高->低 | 局部变量,形参,返回值 |
heap | 手动 | 低 | 低->高 | new/malloc动态申请 |
STL构成
Standard Template Library
常见:容器、算法、迭代器
罕见:迭代适配器、空间配置器、仿函数
vector和list异同
- vector底层是array(随机读取快),list底层是双向链表(增删快);
- vector插入节点导致内存拷贝而list不会;
- vector分配好内存不够双倍扩展,list每次插入都申请内存。
const成员函数
const在前表示返回值为const类型
const在后表示函数是const不能修改成员变量
内存分类
堆区、栈区、全局(静态)区、文字常量区、程序代码区。
例如,函数内声明一个char*字符串,首指针位于栈区,所指字符串内容位于文字常量区