复习-----C/C++

一、指针与引用的区别(从不同的角度入手)
1、引用是C++才有的,在c++11新标准中之前只有一级引用,之后出现了二级引用
2、(从汇编角度来说)看下面一个例子:
int a = 3;
int *b = &a;
008E41F5 lea eax,[a]
008E41F8 mov dword ptr [b],eax
 *b = 5;
008E41FB mov eax,dword ptr [b]
008E41FE mov dword ptr [eax],5

int &c = a;
008E4204 lea eax,[a]
008E4207 mov dword ptr [c],eax
  c = 6;
008E420A mov eax,dword ptr [c]
008E420D mov dword ptr [eax],6
指针和引用的汇编代码是完全一样的
3、定义时:指针可以不用初始化,但是引用必须要初始化,指明 它所引用的那个地址空间,引用需占内存空间,引用一经定义就无法修改
4、使用时:访问引用变量会自动解引用
二、函数重载
1、定义:在同一作用域下,函数名相同,参数列表不同的函数可以构成重载
WHY??
因为在C++程序编译阶段会产生符号表,在符号表解析以后会给符号分配地址,一个地址只能分配给一个符号,而C++在生成符号时会带上参数类型,所以不同的参数列表是构成重载的一个条件。
##const只有在修饰指针*/引用&时才能够构成重载
##任何程序都仅有一个main函数的实例,不能重载
##重载确定:1)最佳匹配原则    2)通过隐式转换
三、C++的多态原理
c++的多态分为静多态和动多态
##静多态是由函数重载和模板实现的,即在编译时期已经确定好调用哪个函数
##动多态是由虚函数实现的,在继承关系中,基类指针指向不同的派生类对象,通过指针调用不同的派生类对象的同名覆盖函数,动多态是在运行时才能根据基类指针所指对象的类型确定调用哪种方法。
##编译阶段生成虚函数表,虚函数表不属于对象内存,存放在只读数据段
##静态绑定即在编译阶段确定函数版本,将函数入口地址写入寄存器中
##动态绑定即在编译时期生成虚函数表,将函数地址写入虚表中,运行时期根据基类指针所指的派生类对象确定调用的函数版本
四、可能发生内存泄漏的情况
1)使用malloc开辟内存,没有free
2)使用new动态地开辟了数组,但是只使用delete释放了0号元素的内存
3)在发生浅拷贝时,赋值之前没有释放原来的内存空间
4)智能指针交叉引用
5)在堆上创建对象,析构函数没有写成虚函数
6)构造函数抛出异常
7)打开文件后,没有执行相应的关闭文件的操作
8)僵尸进程,内核控制块泄露
9)linux上文件描述符fd泄露
五、关于malloc
底层实现:
在glibc上,malloc底层是由ptmalloc实现的
在linux上,malloc底层是由do_brk和do_mmap实现的
六、STL容器
顺序容器
vector(向量容器,底层是数组)     deque(双端队列,底层是二维数组)      list(双向链表容器)  
C++新标准增加两个forward_list(单向链表。只支持单项顺序访问,在任何位置插入/删除都很快) 
array(固定大小数组,支持快速随机访问,不能添加或删除元素)
关联容器
set(单重集合)   multiset(多重集合)    map(映射表:不允许key值重复)  multimap(多重映射表:允许key值重复) 
C++新标准增加了hashmap,hashset
容器适配器(底层没有自己的数据结构,不提供迭代器)
stack   默认的底层实现为vector,不允许随机访问堆栈元素
queue   底层默认为deque,不允许 随机访问队列元素
priority-queue  底层实现默认为vector(max-heap:大根堆),最大的元素总是在队首,不提供便利功能,也不提供迭代器
六、设计模式 23种
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点
//单例模式
class Singleton
{
    private:
        static Singleton instance;
        //私有其构造方法,堵死了外界利用new创建此类实例的可能
        Singleton()
        {
            //....
        }
    public:
        static Singleton GetInstance()
        {
            if(instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }       
}
//上述单例模式 使用静态初始化方式,在自己被加载时就将自己实例化,因此称为快加载
##进行优化,要在第一次被引用时,才会将自己实例化(懒加载),定义为静态的指针
?多线程下的单例模式?(使用互斥锁)
static Singleton GetInstance()
 {
            pthread_mutex_lock();//加锁
            if(instance == null)
            {
                instance = new Singleton();
            }
            pthread_mutex_unlock();//解锁
            return instance;
  }
//频繁的加锁解锁会造成性能的降低,优化使之高效,加二次判断      
static Singleton GetInstance()
 {
            //先判断实例是否存在,不存在再加锁处理
            if(instance == null)
            {
                pthread_mutex_lock();//加锁
                if(instance == null)
                {
                    instance = new Singleton();
                }
                pthread_mutex_unlock();//解锁
                return instance;
            }
   }       
七、编译链接
编译:预编译  编译   汇编
1)预编译--------》产生.i文件
##将所有的“#define”删除,并且展开所有的宏定义
##处理所有条件预编译指令,如: #if    #ifdef   #elif   #else   #endif
##处理#include预编译指令,将被包含的文件插入到该预编译指令的位置。注意这个过程是
递归进行的,也就是说别包含的文件还可能包含其他文件
##删除所有的注释
##添加行号和文件名标识以便编译时编译器产生调试用的行号信息以及用于编译时产生编译错误或警告时能够显示行号
##保留所有的#program编译器指令
2)编译:对预处理文件进行一系列的词法分析、语法分析、语义分析及优化后产生相应的汇编代码文件
3)汇编:将汇编代码转化为机器指令
链接:将目标文件.o/.obj文件与库一起链接

可执行文件格式:windows下的PE和Linux下的ELF(参考《程序员的自我修养》)






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值