嵌入式课前知识
2017-12-05 14:25:03 23 举报
AI智能生成
嵌入式学习班要点,主要是我个人不熟悉的部分
作者其他创作
大纲/内容
嵌入式定义
以用户需求为核心
软硬件可裁剪
性能合适
功能小
体积合适
可靠性高
上位机
PC机
安装纯linux系统
下位机
开发板
看硬件
粗看
基本硬件信息
三大件:处理器、内存、闪存(相当于硬盘)
外围接口
LVDS LCD MIPI
接屏
UART0
接GPS、GPRS、BT(蓝牙)
网口
USB。。。
细看
原理图
芯片手册
UNIXC01
day01
计算机框架
操作系统
GNU
计算机语言发展
man
man 3 库函数(printf)
man 2 系统调用函数
man 1 命令
gcc
预处理
gcc -E *.c -o *.i
编译到汇编(AT&T)
gcc -S *.i -o *.s
编译到机器语言
gcc -c *.s -o *.o
链接
gcc *.o -o *.out
大型软件开发的组织架构
编译多个源文件
gcc *.c -o *.o
链接多个源文件
gcc *.o -o *.out
gcc -v *.o -o *.out
-v显示所有处理过程
其他.o文件是运行时文件
显示<>include的系统指定路径
查看符号表
nm *.o或*.out
解析2进制文件
00000000 T func
T代表.o文件中实现了该函数
U func
U代表.o文件中使用了但没实现该函数
静态链接:编译时链接
动态链接:代码加载到内存时链接
C语言
函数指针
函数指针做参数
int func(int(*f)(int), int x);
函数指针声明
int (*pfunc)(int);
函数指针数组声明
int (*pfunc[2])(int)={fun0,fun1};
类型别名
typedef int iii;
iii i; //=int i;
typedef char *string_t;
string_t str; //=char *str;
struct st_t{};
typedef struct st_t st_s;
st_s t; //=struct st_t t;
typedef char Line[10];
Line text; //=char text[10];
typedef void (*f)();
f func;//=void (*func);
大、小端
网络传输多大端
计算机多小端
day02
变量
shell与操作系统对话时需要的一些信息
自定义变量
变量名=变量值
环境变量
env查看所有
变量名=变量值
查看:
echo $环境变量名
echo "$环境变量名"
PATH
which 程序名
export PATH=$PATH:/newpath
export PATH=newpath:$PATH
~
当前用户的home目录
PS1
命令提示符
静态库lib*.a
生成
ar -r lib*.a *.o
查看
ar -t lib*.a
链接.a
gcc *.o -Ldir(绝对或相对) -llibname(静态或动态) -o *.out
强制静态链接,不加的时候,动态库优先
gcc -static ...
LIBRARY_PATH
动态库lib*.so
生成动态库,与位置无关代码
gcc -c -fPIC *.c #生成.o
gcc -shared -o lib*.so
gcc *.c -Ldir -llibname -o *.out
gcc -c -fPIC *.c #生成.o
gcc -shared -o lib*.so
gcc *.c -Ldir -llibname -o *.out
加载器
使用环境变量:LD_LIBRARY_PATH
默认路径:/lib,/usr/lib
可省略-Ldir
动态加载
#include
dlopen(3)
dlclose(3)
void *p=dlopen("*.so", RTLD_NOW);
if (p != NULL){
func_t *func=(func_t*)dlsym(p, "func_name");
if (func != NULL){
func(...);
}else{
printf("%s",dlerror());
}
dlclose(p);
}else{
printf("%s",dlerror());
}
如果有#include
gcc *.c -ldl
获取dlopen的错误信息
dlerror(3)
获取函数地址
dlsym(3)
day03
错误处理
最近的一个系统错误
errno
perror(3)
perror(s)==>打印:s+": "+error message+'\n'
获得错误信息
strerror(errno)
GDB
生成带有调试信息的输出
gcc -g *.c -o *.out
gdb *.out
l
列出代码
b 行号/函数名
设置断点
r
运行
p 变量名
看值
n
next
s
step in
q
退出
辅助工具
反汇编
objdump -S a.out
去除冗余
strip *.out
查看共享依赖库
ldd *.out
配置管理共享库
ldconfig
内促管理与进程
cpu
寄存器
段寄存器
CS
DS
ES:附加段
SS:stack segment
内存
线性地址/虚拟地址
栈
栈帧 每函数
代码段
字符串
数据段
static
堆
malloc
物理地址
物理内存和虚拟内存
进程
用户空间:0~3G
内核空间:3G~4G
getpid
cat /proc/pid号/maps
day04
虚拟内存
映射文件或设备到内存空间
mmap(2)
解除映射
mumap(2)
mmap(addr, length, prot, ..,-1,0);
malloc/free的底层实现
malloc缓冲机制
malloc第一次分配33块4K空间,如果够用,后续不会再分配块
brk(2),sbrk(2)
文件
open(2)返回文件描述符,fd,0标准输入,1标准输出,2标准错误输出
read(2)
write(2)
close(2)
#include
#include
#include
类型
-普通
d文件夹
b块设备文件
c字符设备
ssoccket文件
l软链接
p管道
权限
rwxrwxrwx
u(user)g(group)o(other)
a(all)
chmod
umask,文件默认权限掩码
进程
PCB
进程控制块Proccess Control Block
记录进程使用计算机资源
day05
文件读写与随机访问
lseek
#include
内存映射的建立与解除
fd=open(...)
mmap(addr, length, prot, ..,fd,0);
close(fd);
文件元数据
文件的属性
inode
stat(1/2) file
硬链接,共享inode的文件
ln file
软连接,指向inode的inode
ln -s file
getpwuid
getgrnam
getgrgid
/etc/pwsswd
block
day06
文件的内核结构与描述符
opendir
closedir
readdir,每次返回文件夹下的一条
文件重定向,输出重定向>
复制文件描述符
dup
dup2
新描述符与原描述符都指向原描述符文件
文件锁
强制锁
建议锁
写锁(互斥锁)
读锁(共享锁)
fcntl
F_SETLK
尝试操作,失败立即返回
F_SETLKW
尝试操作,失败则等待
F_GETLK
查看锁状态
库函数和系统调用
库函数有基于内存的读写缓冲,系统调用没有读写缓冲
子主题 2
进程
程序是指令的集合
进程是程序运行的实例,每个都有自己的pid和PCB,是资源分配的基本单位。
linux:进城之间是父子或兄弟关系,所有用户进程构成一棵树,pstree
init进程,pid=1,用户的第一个进程。
环境变量才可以被子进程继承
创建进程
fork
复制父进程PCB,创建新pid,父进程拿到的pid!=0,子进程中的pid=0
分类
交互式
批处理
守护/精灵
UNIXC02
day01
终止进程
return
只是函数返回
exit(3)
_exit(2)
进程退出
子进程被init继承,这些进程成为孤儿进程
on_exit(3)
atexit(3)
注册进程终止事件函数
回收子进程
父进程回收资源
wait(2),等待进程改变状态
waitpid(2),等待指定进程改变状态,默认等待进程结束
僵尸进程,未被回收的死亡进程
创建子进程
exec*
直接生成子进程
system(3)
system("ls -l");
通过sh执行
day02
环境变量
extern char **environ
字符串列表
int main(int argc,char *argv[],char *envp[])
envp,环境变量
getenv(3)
setenv(3)
putenv(3)
文件重定向
dup2(fd_from,fd_to)
<-fd_to = <-fd_from
管道
有名
mkfifo(3)
文件类型p
无名
亲缘进程通信用
pipe(3),参数0读,1写
进程中关闭不用的fd后操作使用的fd
进程通信用,单向
信号
软中断
软件模拟中断
进程异步通信机制
kill -l查看信号
一般有64个信号,32、33没有
2
ctrl+c
3
ctrl+\
9
杀进程
12
用户自定义
11
段错误
14
闹钟
17
sigchild
kill -信号编号 pid
信号状态
信号未决
信号正在传输
产生、未决、阻塞、进程对信号捕获、信号处理程序
进程对信号默认处理
终止当前进程
SIG_DFL
缺省
SIG_IGN
忽略
注册信号处理函数
signal(2)
typedef void (*sighandler_t)(int);
sighandler_t signal(信号编号, 信号处理函数);
sighandler_t signal(信号编号, SIG_IGN);
sighandler_t signal(信号编号, SIG_DFL);
产生
硬件产生
linux命令
kill -信号编号 pid
kill(2)
raise(2),向当前进程发送信号
alarm(2)
秒级传递闹钟信号
返回剩余秒数
day03
信号集与信号屏蔽
sig*(3)
sigemptyset
清空信号集
sigfillset
置位信号集
sigaddset
添加信号to信号集
sigdelset
产出信号from信号集
sigismember
测试信号是否是信号集成员
sigprocmask
检测或改变信号
阻塞
sigset_t block;
sigemptyset(&block);
sigaddset(&block,SIGINT);
sigprocmask(SETMASK,&block,NULL);
SIG_BLOCK
并集
SIG_UNBLOCK
移除设置值
SIG_SETMASK
设置阻塞集
9(SIGKILL)和19(SIGSTOP)阻塞不了
可靠信号,阻塞时不会丢失,实时信号
34~64
不可靠信号,阻塞会导致丢失,非实时信号
1~30
sigpending
检测当前进程未决信号
子进程继承父进程的信号处理函数
睡眠
sleep(2)
暂停
pause(2),等任意信号
闹钟
alarm(2)
发送信号
信号处理过程
用户按下ctrl+c,键盘产生硬件中断
如果CPU正在执行这个前台进程,则该进程用户空间代码暂停执行,CPU从用户态切换到内核态处理硬件中断
前台进程驱动将ctrl+c解释成一个SIGINT信号,记录在该进程的PCB中
当某时刻进程切回用户态,首先处理PCB中记录的信号,找到信号处理程序处理
信号处理函数处理完毕,调用sigreturn(2),继续返回到内核态,返回上一步
可重入函数
使用到的变量全部分配在栈帧中的函数
信号处理函数尽量可重入
定时器
用户时间
用户态时间
内核时间
内核态时间
睡眠时间
等待I/O、睡眠等不被调度的时间
内核为每个进程维护三个计时器
真实ITIMER_REAL
统计进程执行时间
可发送SIGALRM
虚拟ITIMER_VIRTUAL
统计进程用户时间
可发送SIGVTALRM
实用ITIMER_PROF
统计进程的用户时间和内核时间
可发送SIGPROF
setitimer(2)
UNIXC03
day01
XSI的IPC对象
system v IPC
ipcs
查看system v IPC对象
ipcrm
移除对象
获取一个键值
通过键值获取一块内存,返回内存id
通过内存id操作内存
ftok,文件名转化为键值
消息队列
msgget(2)
从键值获取消息队列id
msgsnd(2)
发送消息
msgrcv(2)
接收消息
共享内存
shmget(2)
从键值获取共享内存id
shmat(2)
绑定到当前进程
shmdt(2)
解除绑定
day02
网络与网络协议
所有网络编程都是基于客户端和服务器架构
网络通讯
TCP/IP协议簇
4层(不算物理层)或5层
应用层
用户进程,处理应用程序细节,其他层是内核进程,处理通信细节
用户进程
可以监听端口号
FTP
传输层
UDP
TCP
网络层
ICMP
IP
根据协议类型分配
IGMP
链路层
网帧定义
以太网协议
令牌环网协议
ARP
硬件接口
根据报文类型分配
RARP
物理层
物理层协议
水晶头尺寸
电气协议
IP地址
IPV4
分类
A
0+7位网络号+24位主机号
B
10+14位网络号+16位主机号
C
110+21位网络号+8位主机号
D、E
IPV6
128位
物理地址
网卡MAC,6字节
ifconfig
端口号
网络设备
HUB集线器
放大信号+分流,多用户分时复用,用户间不能直接通信
工作在物理层
交换机
交换网帧
工作在链路层
维护一个局域网
路由器
交换IP数据包
工作在网络层
可以跨局域网
TCP客户机/服务器
服务器
创建套接字
socket(2)
绑定
bind(2)
监听
listen(2)
接收
accept(2)
read(2),write(2)
客户机
创建套接字
socket(2)
绑定
bind(2)
连接
connect(2)
完成3次握手
read(2),write(2)
day03
线程
程序的执行的最小单位
共享进程的代码段、数据段、堆区
gcc *.c -lpthread
同步
互斥锁
pthread_mutex_init(3)
pthread_mutex_lock(3),pthread_mutex_trylock(3)
pthread_mutex_unlock(3)
pthread_mutex_destroy(3)
条件变量
pthread_cond_init(3)
pthread_cond_wait(3),pthread_cond_timewait(3)
pthread_cond_signal(3),pthread_cond_broadcast(3)
pthread_cond_destroy(3)
信号量
sem_init(3)
sem_wait(3)
sem_post(3)
sem_destroy(3)
UDP客户机/服务器
创建套接字
socket(2)
绑定
bind(2)
recvfrom(2),sendto(2)
并发
线程
多路复用
进程
父进程监听,子进程处理
day04
信号量集
创建键值
ftok
获取信号量集标识符
semget
PV操作
semop
设置或获取信号量值
semctl
UNIXC补充
C语言
非静态指针参数:值结果参数
查看文件与ascii码表
od -tx1 -tc file
密码,/etc/shadow
获取日历时间
ctime(3)
chdir(2)
实现cd
getcwd(2)
实现pwd
硬链接
link(2)
unlink(2)
软链接
symlink(2)
ps -aux
CPATH/C_INCLUDE_PATH
C头文件的附加搜索路径
CPLUS_INCLUDE_PATH
C++头文件的附加搜索路径
uname -a
作业
前台作业
ctrl+z,切到后台并暂停,显示作业号
后台作业
jobs,显示后台作业
fg %作业号,切到前台
bg %作业号,后台运行
实际用户getuid和有效用户geteuid
P操作
passeren
通过
V操作
vrijgeven
释放
STDCPP01
day01
无命名空间
::
namespace
using namespace name;
相对全局
using name::membername
相对局部
union
可以无名,直接使用变量
struct
可以有函数成员,成员函数可以访问变量成员
enum
独立数据类型
string
string.c_str()->char*
操作符别名
or,and,...
day02
重载
重载一般匹配规则:
完全>常量转换>升级转换>降级转换>省略号转换
编译时换名来实现
阻止C++编译器换名
可以只对声明使用即可
extern "C"
extern "C" {}
作用域相同才能构成重载
class A,B{foo(){}};
class C: public A,public B{
A,B同名函数不构成重载
using A::foo;
using B::foo;
A,B同名函数构成重载
}
缺省参数
定义时可以不写缺省值
哑元参数
没有形参变量名
为了兼容过去代码
参数已经没有使用价值,令原来的参数变成哑元参数
区分前后++/--
内联函数
会做内联优化,类似于宏
代码段直接放在调用者代码段内
实际是否进行内联由编译器决定
动态内存分配
new同时可以初始化
引用
即别名,操作引用等于操作原变量
声明时必须绑定变量
类型一般要一致
没有实参压栈
本质是指针
指向不可修改
不能定义指向应用的指针
不能定义引用的引用
不能定义引用数组
数组的引用
int (&a)[3] = array;
day03
类型转换
强制类型转换
静态类型转换
static_cast<目标类型>(源类型变量)
转void* to other
动态类型转换
dynamic_cast<>()
常类型转换
const_cast<>()
去除指针或引用的常属性
const int a;
const int *pa = &a;
int* b = const_cast(pa);
编译器优化会把a,pa类似宏一样替换,则通过b访问他们的时候,不会作用到其他使用a和pa的地方。
可以使用volatile关键字去优化,const volatile int a;
重解释类型转换
reinterpret_cast<>()
任意类型指针或引用之间转换
指针和整数之间转换
int addr;
int *paddr = reinterpret_cast(addr);
类和对象
class/struct
访问控制限定符
class默认private,struct默认public
构造函数
类名()[:初始化表]{}
一般成员函数
返回类型 函数名(形参表)[const]{}
day04
构造函数
多文件编程
类对象的创建
对象数组
栈区,classname array[]={classname(...),...};
堆区,classname *parray = new classname[]{classname(...),...};
构造函数
类型转换构造函数
classname(typeA a){}
classname x = (typeA)k;
类型转换必须显示转换
explicit classname(typeA a){}
classname x = (typeA)k;
拷贝构造函数
A(const A& a){}
A a0;
A a1(a0);
A a2 = a1;
默认按字节复制
浅拷贝
场景
用已定义的对象初始化
向函数传递参数
从函数返回对象
day05
初始化表
A(int i):member0(i),member1(6876),object(43,432){}
必用场景
有没有无参构造函数的类对象成员
有const和引用成员
成员初始化顺序以声明顺序为准
适用拷贝构造函数
this指针
对象函参数隐藏参数
必须显示使用场景
区分作用域
返回调用对象
销毁自身对象
delete this;
常函数
返回类型 函数名(形参)const{}
const *this
mutable
常函数中可修改成员变量修饰符
可以与非常函数构成重载
析构函数
STDCPP02
day01
拷贝构造与拷贝赋值
class& operator=(class c){}
默认=运算符返回自引用
静态成员
classname::staticvar
object.staticvar
classname::staticfunc
object.staticfunc
单例模式
定义
只允许创建一个对象的类创建模式
禁止外部创建对象
私有构造函数
类内部维护唯一对象
静态成员变量
提供访问单利对象方法
静态成员函数
创建方法
恶汉式
程序启动时创建
懒汉式
使用时创建,不用时销毁
day02
成员指针
成员变量指针
string classn::*ps = &classn::s
obj.*ps;//s
pobj->*ps;//s
成员函数指针
返回类型 (类名::*函数指针)()=&类名::成员函数名
(对象.*成员函数指针)()
(对象指针->*成员函数指针)()
操作符重载
双目
全局函数形式
友元函数
可以在不同类型间重载,特别是左操作数不可修改时
成员函数形式
下标
函数操作符
()
->,*
智能指针
auto_ptr
类型转换构造函数
operator 目标类型(void)const{}
new/delete
static void* operator new(size_t size){}
static void operator delete(void* p){}
不能重载
作用于
::
成员访问
.
解引用
.*
?:
sizeof
不会运算
typeid
所有操作数都为基本类型
不会改变优先级
不会改变操作数个数
不能用其他符号
不能用全局重载
=,(),[],->
友元函数
friend
可以访问类的任何成员
day03
继承
继承方式
影响子类中父类成员访问权限
内存排布
父类成员
子类成员
子类地址给父类指针
向上造型,隐式转换
父类地址给子类指针
向下造型,显示转换
static_cast
只有公有继承可以
强制转换可突破
初始化表中调用基类构造函数
子类构造函数
过程
分配内存
构造基类子对象
构造成员子对象
构造子类
析构过程相反
day04
子类拷贝构造函数
使用基类的对应函数
必须显示调用基类拷贝构造
多重继承
虚继承
钻石继承
A
/ \
B C
\ /
D
B:virtual public A
C:virtual public A
A的对象仅有一份,并为中间子类共享
多态
子类同名函数也变成虚函数
day05
纯虚函数
抽象类
有纯虚函数的类
简单工厂方法模式
父类使用纯虚函数工作,子类完成虚函数
虚析构函数
用父类指针析构子类对象
子类析构函数会自动调用父类
day06
运行时类型信息
typeid
可以获取多态下的实际类型
==,!=
动态类型转换
针对多态特性,检查转换合理性
异常
C语言远跳
setjmp
longjmp
try{}catch(int ex){}catch(异常类型){}
throw
没有捕获的异常会被系统捕获,杀死进程
子类异常引用类型会被基类异常类型捕获,所以子类捕获放前面
异常说明
异常说明以外的异常不能捕获
空异常说明
不能捕获任何异常
函数声明和定义的说明要一致,顺序可变
多态子类虚函数说明不能比父类多
exception
.what()
构造函数抛出异常,被捕获后会不完整构造
I/O流
格式化流
格式化函数
cout.percision(n)...
流控制符
setprecisition(n)...
STDCPP补充
C/C++函数声明可不写形参
左值
可以放在等号左边的值
右值
只能放在等号右边的值
const char *p;
char const *p;
const修饰char,即char不可改变
char* const p;
const修饰p,即p不可改变
cout打印地址,void*总可以识别对,不识别就会当作bool类型输出
访问修饰符只在编译阶段起作用
QT01
Assistant
手册
编码
信号和槽
QT对象通信机制
QObject::connect(&发送类对象,SIGNAL(sender()),
&接收类对象,SLOT(receiver()));
可以传递缺省参数
信号函数的多与参数会被忽略
容器
parent
自动delete子控件
父窗口
QWidget
resize(int,int)
move(int,int)
QMainWindow
QDialog
面向对象的QT编程
QLineEdit
可以复制文本
QHBoxLayout
布局器
QDoubleValidator
验证
自定义信号函数:
Q_OBJECT//独立行,令qt编译器先处理QT扩展语法
public/protected/private slot:
void slot_func(...)
signals:
void signal_func(...)
发射信号
signals:
void sig_func(...);//只能声明,不能写定义
void func(...){
emit sig_func(
signal_func();
);
}
QMessageBox\QFrame\QDialogButtonBox
paintEvent\timerEvemt\mousePressEvent\mouseReleaseEvent\mouseMoveEvent\KeyPressEvent\KeyReleaseEvent
QDir\Qrect\Qtime\Qvector\Qpair\foreach
Designer
uic *.ui -o ui_*.h
QCreater
QT02
数据库
以一定方式存储在一起,能为多用户共享,具有尽可能小的冗余的特点,与应用程序彼此独立的数据集合
缩写
DB
数据库
DBMS
管理系统
DBA
管理员
RDB
关系型
RDBMS
关系型管理系统
常见
Oracle,50%
IBM:DB2,20%
MS:SQLserver,15%
Sun/oracle:MySql
SQLite
开源轻量级嵌入式关系型
SQL
结构化查询语言
--注释
子主题 3
创建表
CREATE TABLE 表名(
字段名0 类型 约束0 约束1...,
...
);
类型
INT
TEXT
REAL
约束
PRIMARY KEY
NOT NULL
删除表
DROP TABLE 表名;
插入数据
INSERT INTO 表名(字段名,...)VALUES (值,...)
删除数据
DELETE FROM 表名 WHERE condition
查询
SELECT [DISTINCT] 字段名,... FROM 表名 [LIMIT 行数] [OFFSET 记录条数] [WHERE condition] [LIKE %X_X%XX_] [ORDER BY 字段 ASC/DESC];
修改
UPDATE 表 SET 字段0=值,字段1=表达式... [WHERE condition]
WHERE条件
字段名=xxx
运算符
比较运算
逻辑运算
位运算
sqlite
sqlite3 xx.db
命令
.help
.databases
.table
.schema
.header on/off
.separator
.mode column
.show
.width
nullvalue
.read
导出
.output *.txt
备份
.backup *DB *.db
恢复
.restore *.db
QT使用数据库
QSqlDatabase
addDatabase
setDatabaseName
open
QSqlQuery/QSqlQueryModel
QTableView
QT多线程
QThread
moveToThread
继承,重写run,成员变量传参
同步
阻塞
wait
终止
terminate
setTerminateEnable
exit
QMutex
QReadWriteLock
QSemaphore
QWaitCondition
QT网络编程
主机信息
QHostInfo
QNetworkInterface
QHostAddress
UDP
QUdpSocket
TCP
QTcpSocket
QTcpServer
HTTP
请求格式
请求行
请求内容+http版本
请求头
Content-Type
\r\n
消息
响应格式
状态行
HTTP版本
状态码
状态码描述
响应头域
服务器相关信息
Content-Type
空行
\r\n
消息体
QNetworkAccessManager
QNetWorkReply
QNetworkRequest
守护进程
父进程fork并推出
子进程调用setsid创建新会话
切换根目录为/,chdir("/")
设置权限屏蔽码0,umask(0)
关闭不需要的文件描述符
fd = open("/dev/null",R)
dup2(fd,0);dup2(fd,2);dup2(fd,2);
STL
语言
动态语言
脚本语言
静态语言
编译语言
优点
高性能
运行安全
缺点
编译时间长
灵活性差
模板
函数模板
template
namex 函数名(namex var0,...){}
调用处编译,延迟编译/二次编译
隐式推断
模板类型相关
参数与模板类型相关
模板类型相关可省略尖口号
不能隐式类型转换
重载的选择
优选重载争取在一次编译被选中
如果后面参数可以隐式推断,可以仅前面缺省
不能是virtual
无法构造虚函数表
延迟编译阻碍了静态构建虚函数
类模板
template<typename 参数类型0,...>
class name:public 参数类型x{
}
class name:public 参数类型x{
}
不能隐式推断
实例化
类
编译时
对象
运行时
模版可带非类型参数
仅限于整数
不能用浮点数
不能用类对象
前面参数可做后面参数缺省值
参数类型可带缺省值
typename
用于模板
解决嵌套依赖
在第一次编译时,编译器不认为T是类型名时,会出现嵌套依赖,tyoename,可以显式指定类型名
内部模板的外部定义
类模板参数
template<typename [namex]> class name
0初始化
T v=T();
编译模型
单一模型
实现声明在同一文件
优点:集成度高
缺点:难于维护,难于协作
分离模型
声明实现分文件放
优点:易于维护,易于协作
缺点:无法对模板二次编译
包含模型
头文件尾部包含cpp文件
优点:解决模板分离模型问题
缺点:暴漏cpp,不能最小编译
实例模型
cpp中预实例化,强制二次编译
优点:代码不公开,最小编译
缺点:实例化类型有限,限制通用性
导出模型
export声明,强制末班内部表示延迟到二次编译,export template<..>
优点:保护代码,最小编译,类型不受限
缺点:多数主流编译器不支持
新编译器废除
struct\class\typename
struct
声明类,默认访问public
class
声明类,默认访问private
模板类型参数
typename
模板类型参数
解决嵌套模板
template
声明模板
嵌套于类模板中的函数模板
template<typename T>
void foo(){
X<T> x;
x.template func<int>();
}
void foo(){
X<T> x;
x.template func<int>();
}
广义多态
一种形式,多种功能
动态多态
虚函数
动态绑定
静态多态
类型参数和模板
预编译头
g++ -c *.h->*.h.gch
微软*.pch
容器
线性容器
向量
vector
连续内存和下标访问
双端队列
deque
列表
list
适配器容器
堆栈
stack
队列
queue
优先队列
priority_queue
关联容器
pairs
映射
map
多重映射
multimap
集合
set
多重集合
multiset
类要求
缺省构造函数
深拷贝的拷贝构造和靠拷备赋值运算符函数
重载==或<
泛型算法
迭代器
迭代特性
单向
双向
方向
正向
反向
迭代运算
顺序迭代
随机迭代
目标访问
可写
只读
0 条评论
下一页