C++编程基础知识三
1、语句:
①符合语句也被称作块,一个块就是一个作用域,在块中引入的名字只能在块内部以及嵌套在块中的子块里访问;
②switch语句:如果某个case标签执行成功,将从该标签开始往后顺序执行所有case分支;
break命令:终止循环过程;
【注】:一般不要省略case分支最后的break语句,如果没写break语句,最好加一段注释说明清楚程序的逻辑;
③跳转语句:中断当前的执行过程;
C++语言提供了4种跳转语句:break,continue,goto,return;
break:终止离它最近的while,do while,for,swtch语句;
continue:终止最近循环中的当前迭代并立即开始下一次迭代;跳出本次循环,执行下一次循环;
goto:从goto语句无条件跳转到同一函数内的另一条语句;
【注】:不要在程序中使用goto语句,因为它使得程序即难理解又不好修改;
return:终止当前正在执行的函数并将控制权返回到调用该函数的地方;

2、异常:存在于运行时的反常行为;
典型异常:意外输入,失去数据库连接等;
异常处理:
throw:表示遇到了无法处理的问题,throw引发了异常;
try:处理异常,以一个多多个catch子句结束;
异常类:用于在throw和相关catch子句之间传递异常;
标准异常:


3、函数:
函数只能定义一次,但可以声明多次;
重载函数:同一个名字可以对应几种不同的函数;
函数调用完成两项工作:实参来初始化函数的形参;控制权转移给被调用函数;
【注】:在C++语言中,名字有作用域,对象有生命周期;
形参和函数体内部的变量统称为局部变量;
①局部静态变量static:局部变量的生命周期贯穿函数调用及之后的时间;
在程序执行路径第一次经过对象定义语句时初始化,并且直到程序终止才被销毁;
在此期间,即使对象所在的函数结束执行也不会对它有影响;
②参数传递:
值传递:形参是实参的拷贝,改变形参的值并不会影响外部实参的值;
指针传递:传递的是一个外部实参的地址,当被调用函数的形参发生变化时,实参也会变化;
引用传递:实参和形参通过引用绑定;形参的任何改动都会直接影响到实参;
【注】:当某种类型不支持拷贝操作时,或考本大的类类型对象时比较低效,函数只能通过引用形参访问该类型的对象;
【注】:如果函数无须改变引用形参的值,最好将其声明为常量引用;
③函数同时返回多个值:
方法一:定义一个新的数据类型,让它包含位置和数量两个成员;
方法二:给函数传入一个额外的引用实参;
④数组形参:
数组的两个特殊性质:不允许拷贝数组,使用数组时会将其转换成指针;
当为函数传递一个数组时,实际上传递的是指向数组首元素的指针;
数组的大小对函数的调用没有影响;
⑤管理指针形参三种方法:
使用标记指定数组长度:要求数组本身包含一个结束标记;
使用标准库规范:传递指向数组首元素和尾后元素的指针;
显示传递一个表示数组大小的形参;
⑥main处理命令行选项argc,argv;
int main(int argc,char *argv[]){…};
int main(int argc,char **argc){…};
其中,argc表示数量;
argv是值;
⑦默认实参
【注】:一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值;
内联函数可避免函数调用的开销;inline;
内联机制用于优化规模较小、流程直接、频繁调用的函数;
⑧assert预处理宏:用于检查不能发生的条件;
如果表达式为真,则assert什么也不做;
如果表达式为假,则assert输出信息并终止程序的执行;
⑨函数指针:函数指针指向的是函数而非对象;
函数指针指向某种特定类型;
函数类型由它的返回类型和形参类型共同决定,与函数名无关;
//pf指向一个函数,该函数的参数是两个const string的引用,返回值是bool类型;
bool (*pf)(const string &,const string &);//未初始化
使用:
当把函数名作为一个值使用时,该函数自动转换成指针;
pf = lengthCompare;//pf指向名为lengthCompare的函数
pf = &lengthCompare;//等价
bool b1=pf(“hello”,”good”);//调用lengthCompare函数
bool b2=(*pf)(“hello”,”good”);
bool b3= lengthCompare(“hello”,”good”);//等价调用

4、类:自定义数据类型
①类的基本思想是数据抽象和封装;
数据抽象:是一种依赖于接口和实现分离的编程技术;其中,接口是用户所能执行的操作;实现包括类的数据成员、负责接口实现的函数和私有函数;
封装:实现了接口和实现的分离;封装后的类隐藏了它的实现细节,类的用户只能使用接口而无法访问实现部分;
②成员函数:
成员函数的声明必须在类的内部,定义即可在内部也可在类的外部;
非成员函数;
成员函数通过一个名为this的额外隐式参数来访问调用它的对象;
默认情况下,this的类型是指向类类型非常量版本的常量指针;
定义一个返回this对象的函数:
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
units_sold +=rhs.units_sold;//rhs的成员加到this对象成员上;
revenue +=rhs.revenue;
return *this;//返回调用该函数的对象
}
调用函数:total.combine(trans);//
解释:total的地址被绑定到隐式this参数上,rhs绑定到trans上;结果保存到total.units_sold中;
③构造函数:
类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数;
构造函数的名字和类名相同;
构造函数没有返回类型;
类通过一个特殊的构造函数来控制默认初始化过程,这个函数叫做默认构造函数;
默认构造函数无须任何实参;
【注】:只有当类没有声明任何构造函数时,编译器才会自动地生成默认构造函数;
Sales_data() = default;//默认构造函数;
目的:既需要其他形式的构造函数,也需要默认的构造函数;
构造函数初始化列表:每个成员名字紧跟括号括起来的成员初始值,不同成员的初始化通过逗号隔开;

5、访问控制与封装:
①访问说明符来加强类的封装性;
定义在public说明符之后的成员在整个程序内被访问,public成员定义类的结构;
定义在private说明符之后的成员可以被成员函数访问,但不能使用该类的代码访问,private部分封装了类的实现细节;
【注】:class和struct定义类唯一的区别就是默认的访问权限;
希望定义类的所有成员是public时,使用struct;
希望定义类的部分成员是private时,使用class;
②友元:
类允许其他类或者函数访问它的非公有成员,方式:令其他类或函数成为它的友元;
友元声明friend();
友元声明只能出现在类定义的内部,
最好在类定义开始或结束前的位置集中声明友元;
友元的声明作用仅仅是为了指定访问的权限;
如果希望类的用户调用友元函数,则必须在友元声明之外在专门对函数进行一次声明;
③类类型:每个类定义了唯一的类型;
类可以把非成员函数定义为友元;
类可以把其他类定义成友元;
类可以把其他类的成员函数定义成友元;
【注】:友元函数只能定义在类的内部;每个类负责控制自己的友元类或友元函数;

6、类的静态成员:static,使其和类关联在一起;
①静态成员类型:常量、引用、指针、类类型等;
类的静态成员存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据;
静态成员不属于类的某个对象;
Account对象包括两个数据成员:owner和amount对象;
只存在一个interestRate对象,且被所有Account对象共享;
静态成员函数也不和任何对象绑定在一起,不使用this指针;
②虽然静态成员不属于类的某个对象,但仍然可以使用类的对象、引用或者指针来访问静态成员;
但成员函数不用通过作用域就能直接使用静态成员;
③定义静态成员:
静态成员函数可以在类内部也可以在类外部定义;
static关键字只能出现在类内部的声明语句;
静态成员在类的外部定义和初始化每个静态成员;
一旦被定义,就一直存在于程序的整个生命周期中;
double Account::interestRate = initRate();//定义并初始化一个静态成员;
④编译器分两步处理类:
首先编译成员的声明;
然后编译成员函数体;
因此,成员函数体可以随意使用类中的其他成员而无须在意这些成员出现的次序;
