C++温故而知新----1

来源:互联网 发布:浙江软件考试网 编辑:程序博客网 时间:2024/05/17 15:58
存疑概念:
。名称空间声明的名称链接性默认为外部的(除非引用了常量)?
提醒:
。引用声明时就得初始化
。当函数参数为引用时,实参应是变量,不能是表达式
。对于基本类型,cin使用引用//cin >> n;
。const数据的指针和引用优先于非const数据的指针和引用匹配
重要知识点:
第八章 
8.2 引用
8.2.3引用的属性和特别之处
临时变量、引用参数和const
。生成临时变量情况
1.形参为const
2.实参类型正确不是左值/实参类型不正确,可转化为正确类型
8.2.7何时使用引用参数
主要原因
1.能够修改调用函数中的数据对象
2.提高程序速度

8.3 默认参数
。设置一个默认参数,这个参数的右边都得设置
。声明函数有默认参数,定义时不需要加

8.4 函数重载
。函数特征不包括返回值
。最佳匹配
void stove(double &r1);
void stove(const double &r2);
void stove(double && r3);

8.5 函数模板
template <class T>
void swap(T a,T b)
{
T temp;
temp = a;
a = b;
b = temp;
}
8.5.3显示具体化---提供具体化的函数定义
第三代具体化
。对于给定函数名,可有非模板函数、模板函数和显示具体化模板函数以及他们的重载
。显示具体化的原型和定义以template<>开头,通过名称指出类型
。具体化优先于常规模板,而非模板优先于具体化
8.5.4实例化和具体化
。隐式实例化
通过使用模板函数
。显示实例化
直接用命令,令编译器创建特定实例
template void swap(int &,int &);//与具体化有区别
8.5.5编译器使用哪个版本
完全匹配(常规优先于模板)>提升转换(char,shorts自动转为int)>标准转换(int转为char)>用户定义转换(类声明中定义)
。自己选择匹配
void swap(int a,int b);
template<class T>
void swap(T a,T b);

swap(a,b); //使用常规
swap<>(a,b); //显示指出使用模板

8.5.6 模板函数的发展
2.关键字decltype(decltype(expression) var)
int x;
decltype(x) y;//y与x类型相同
decltype(x + y) xpy = x + y;
1。若expression是一个没有括号扩起的标识符,var与标识符相同
2。若expression为函数调用,var类型参照函数原型,不实际调用
3。若expression为一个左值,var为其类型的引用(用括号扩起expression)
decltype((xxx)) r = xxx;//r为一个xxx的类型的引用
4.以上均不满足,则与expression的类型相同
*以上四条按顺序判定
3另一种函数声明法
auto h(int x,float y) -> double;
auto h(int x,float y) -> double{}

template<class T1,class T2>
auto gt(T1 x,T2 y) -> decltype(x + y){}

第九章
9.2 存储持续性、作用域和链接性
9.2.1作用域和链接
。链接性描述了名称如何在不同文件直接共享。如自动变量无链接性,所以不能共享。
9.2.3静态持续变量
int global = 100;//外部链接性
static int one_file = 50//内部链接性
void function()
{
static int count = 0;//无链接性
}
9.2.4静态持续性和外部链接性
1.单定义规则:变量只能有一次定义
变量声明
1.定义声明/定义:给变量分配存储空间
2.引用声明/声明:不分配存储空间,因为引用已知变量
引用声明需extern关键字,且不进行初始化
9.2.5静态持续性和内部链接性
。static限定符用于作用域为整个文件的变量时,链接性为内部
9.2.6静态持续性和无链接性
。将static限定于代码块中,只能在代码块中使用
9.2.7说明符限定符
2.mutable
使在const修饰的类/结构的某个成员可被修改
struct data
{
char name[20];
mutable int access;//若结构被声明为const,access可以改变
}
3.再谈const
C++中,const修饰的全局变量的链接性为内部的
9.2.8函数的链接性
。函数默认有外部链接性,其他文件使用,需要extern的函数原型
。内联函数可以一定程度不受单定义限制(在多个文件定义相同内联函数)
。static修饰的函数为内部链接
9.2.10储存方案和动态分配
1.new运算符初始化
int *pi = new int(6);

struct where{double x;double y};
where *one = new where{2.5,5.3};
int *pdo = new int[4]{1,2,3,4};

int *pin = new int{6};
3.new:运算符、函数和替换函数
new void *operator new(std::size_t);//对应相同delete函数
new[] void *operator new[](std::size_t);//对应相同delete[]函数
*std::size_t是一个typedef
new int; 相当于new(sizeof(int))
new int[20]; 相当于new(20*sizeof(int))
4.定位new运算符
。需要包含头文件<new>,需要提供指定位置的参数
#include<new>
char buffer[50];
char buffer1[50];
int main()
{
char *p1 = new(buffer);
int *p2 = new(buffer)[5];
//静态定位的指针不需要delete释放
//buffer为动态分配时,直接释放buffer即可
return 0;
}

9.3 名称空间
9.3.1传统的C++名称空间
。声明区域:可以在其中进行声明的区域。如变量所在文件对于全局变量,变量所在代码块对于自动变量
。潜在作用域:从变量声明点开始,到声明区域结束
。作用域:变量对于程序来说可见的范围
9.3.2新的名称空间特性
。名称空间可以全局,也可以位于另一个名称空间内,不能位于代码块内。
。名称空间声明的名称链接性默认为外部的(除非引用了常量)
1.using声明和using编译指令
。using声明将特定的名称添加到它所属的声明区域中
在代码块内引入,覆盖全局变量,通过::全局变量名,在代码块中使用全局变量
。using编译指令使所有的名称可用
2.using声明和using编译指令的比较
。编译指令类似于使用了大量的作用域解析符
。声明类似于声明了相应的名称
*假设名称空间和声明区域定义了相同名称。不允许使用using声明。使用using编译指令将名称空间的名称导入该声明区域,则局部版本将隐藏名称空间版本。
3。名称空间其他特性
。名称空间可以嵌套
。名称空间可以使用using编译指令和using声明
。using编译指令具有传递性
4。未命名的名称空间
namespace
{
int ice;
int other;
}
相当于
static int ice;
static int other;