C++ 程序设计特别版学习笔记(一)

                                                                  前言

      本系列笔记在学习裘宗燕的中文译本-------C++程序设计特别版过程中总结出来的比较好技巧

基础技术

引用&

     引用是某一个对象的别名,必须对引用做初始化。引用的效果跟指针一样,但是安全的。

     可以用 extern X& x 在其他地方初始化。

     引用的值在初始化后就不能改变,因此可以作为一个常量指针的。引用初始化需要是左值。

      EX:
         double &d = 1;             //错误的
     但是常量引用 const T& 的初始化不必是左值,甚至可以不是类型T
     [1] 需要进行 到 T的隐式转换
     [2] 将转换结果存储到一个 T临时变量中
     [3] 用该临时变量做初始化
要区分常量引用和对变量的引用
     对变量的引用,引进临时变量,极容易出错误。
     常量引用,不会出现这种情况,因此常量引用作为参数是很经常的。
        Ex:
        const double& d = 1 ;
      <=> double temp = double(1); // 首先建立一个临时对象
          const double& d = temp;
       // 该临时变量将一直存在,直到这个引用的作用域结束
         一般临时对象 作为求值表达式,在该完整表达式的最后销毁。
  指向void* 指针
     一个任何对象类型的指针,可以给void* 指针赋值。但是反之不然。
     但是 void*指针,不知道所指向的变量的类型,因此对void*指针做增量运算是错误的,void* 指针的用法是传递参数。
  
显式类型转换
     (X)x   到类型X 的转换 <=>
     static_cast<X>(x)
     reinterpret_cast<X>(x)      // 进行不相关类型之间的转换,很容易出错,除非是有保证的转换。
     const_cast<X>(x)  清除const 和volatile 限定符的转换
     dynamic_cast<X>(x) 运行中检查转换
 
函数重载
     函数重载的机制:对同一个函数,实现多种功能的操作就是重载。
     函数重载解除歧义的机制:参数个数、参数类型
     重载匹配规则:
      [1] 准确匹配
      [2] 利用提升的匹配
      [3] 利用标准转换
      [4] 利用用户定义的转换匹配
      [5] 利用参数后的省略…匹配
      当这些规则后,注意歧义的出现。
     重载的一些注意事项:
     [1] 重载解析不考虑 函数返回
     [2] 重载一会超越作用域,如果超越作用域的时候,可能出现作用域的屏蔽问题。
 
     手工的歧义性解析
     Ex:
       void f1(char )
       void f1(long)
       int i = 0;
       f1(1)   ?f1(char) or f1(long)
       做手工的歧义解析 inline void f1(int){ return fl(long(n));}
 
       默认参数
       void print(int value,int base = 10)
       inline void print(int value){ return print(value,10); }
 
指向函数的指针
     对一个函数只能做两件事情:调用 或者取到它的地址。
     一个函数名称 相当于这个函数的地址。
 
void error(string   s)
        void (*efct)(string s)   // 声明一个函数指针变量
 
         efct = &error ó efct = error
        通过函数指针去调用函数也必须满足函数解析规则
     
      typedef void (*SIG_TYPE)(int)   // 声明一个函数指针类型
 
     #define 通过替换
     可能有用的宏
     #define CASE break;case
     #define FOREVER for(;;)
    
完全没有必要的宏
 #define beg {
 #define end }
  危险的宏
 #define SQUARE(x) x*x  宏是简单替换的,所以很容易出现错误
 #define INCR_XX   (xx)++
 
拼接两个串成为一个串
#define NAME2(a,b) a##b
 
条件编译
#ifdef arg_two            //arg_two 经过#define
 Do
#endif
 
#if
#else
#endif
对私有成员的保护依靠是对于使用类成员名字的限制
 但是通过地址操作和显式转换可以绕过这些限制。
 
构造、析构
 构造函数,在创建对象的时候自动调用。
 析构函数,在销毁对象的时候调用。
 
 自引用, 可以对该对象实现多次操作。
物理的和逻辑的常量性
 —— this 指针,跟非静态成员函数的属性、对象的属性有关。
       如果是const非静态成员函数,则this指针是具有const属性
       如果类是const 则this指针是具有const
 —— 在非静态 const 成员函数中修改类的属性技术
      通过 const_cast<>(this) 去掉const属性
      通过将变量 用 mutable 修饰
      利用支持缓存技术,可以推广到各种延迟求值:将要修改的成员放在一个独立的结构中,在类声明该结构体类型的指针,利用间接访问技术。
 
构造、析构
[1]命名的自动对象,当程序的执行每次遇到它的声明时建立,离开它所出现的作用块时销毁。
[2]自由存储对象,通过new建立,delete销毁
[3]非静态成员对象,作为另一个对象的成员,与该对象的生命周期一样。
[4]全局对象、名字空间的对象、类的静态对象,在“程序的开始”建立一次,在程序终止时候销毁一次。
[5]临时对象,作为表达式求值的一部分被建立,在它出现的那个完整表达式的最后被销毁。
   如果 临时对象做函数调用的参数,完整表达式应该是在函数调用之前
[6] 一个union成员没有构造函数、析构函数
 
复制构造函数、初始化、赋值
[1] 复制构造函数用于:对象的初始化、函数参数传递、函数值返回、异常。
   复制构造函数的声明格式
   Class X
   {
//……
 X(const X&); // 不然会出现递归调用
    }
 
[2] 初始化,是对象声明的时候,进行的操作。
[3] 赋值是 (不是在声明时)对象 = 对象
 
[4] const 成员,成员引用 必须初始化
 
临时对象
  [1] 临时对象,在其出现的完整表达式的最后被销毁。
  [2] 临时对象,可以作为const引用,和命名对象的初始化。
  [3] 在const引用 表达式中出现的临时对象,在其const引用退出作用块中才被销毁。
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值