您的位置:首页 > 编程语言 > C语言/C++

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

2008-04-02 23:45 281 查看
前言

本系列笔记在学习裘宗燕的中文译本-------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引用退出作用块中才被销毁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: