因为想,所以就写了。有很多东西都是借用c++primer第六版的原文,因为我怕我自己写的可能不是很严谨。但也有自己总结的不少知识点。希望有误之处请不啬赐教。
内联函数inline
1.内联函数在声明和定义的时候都要在前面加上关键字inline,但一般我们声明定义一起写,因为它的函数体很短。2.内联函数在使用的时候是进行代码替换,即直接用这个函数的代码替换到调用内联函数的地方,使用几次就替换几次。3.递归函数不能作为内联函数,即使你这样写了,编译器也不会把递归函数当作内联函数使用,但有的编译器不会。
在调用函数的时候,当有多个匹配的函数时。
函数调用使用的函数版本顺序(从最佳到最差):
1.完全匹配,但常规函数优先于模板函数。
2.提升转换,(如,char和short自动转换为int,float自动转换为double)。
3.标准转换,(如,int转换为char,long转换为double)。
4.用户自定义转换,(如,在类中定义的转换)。
头文件常包含的内容:
1.函数原型
2.使用#define或const定义的符号常量
3.结构声明
4.类声明
5.模板声明
6.内联函数
静态存储持续变量的3种链接性
1.外部链接性(可在其它文件中访问的变量,为全局变量)
2.内部链接性(只能在当前文件中访问的变量,为全局static变量)
3.无链接性(只能在当前函数或代码块中访问的变量,为局部static 变量)
这三种链接性在整个程序执行期间都存在。
链接性是指在一个或多个文件之间共享的特性。
注:如果文件定义了一个全局外部变量,其名称与另一个文件中声明的静态变量名相同,则在该文件中将隐藏全局外部变量。若两个文件中都定义了一个全局外部变量,且其变量名相同,则会发生错误,因为程序包含了同一个变量的两次定义。
注:若要在其他文件中使用该文件定义的全局变量,则需要加关键字extern来声明它。如extern int x;也可以重新定义x。
说明符与限定符c++11
说明符
register //显式地指出变量是自动的。
static //表示变量的内部链接性或静态的
extern //声明引用的变量在其它地方已经定义了(不同文件中)
thread_loacl //用于线程
mutable //改变数据的const属性,使数据可以改动
限定符
const //指明数据是常量
volatile //即使程序代码没有对内存单元进行修改,其值也可能发生变化。
using声明和using编译
using声明是使特定的标识符可用,如,using std::endl;
using编译是使整个名称空间可以,如,using namespace std;

使用类对象的程序都可以访问类的public部分,但只能通过公有成员函数或者友元函数来访问类的私有部分。
public成员函数是程序和对象的私有之间的桥梁,提供了对象和程序之间的接口。防止程序直接访问数据被称为数据隐藏。
接口就是类中public声明的成员函数。
将类成员函数的声明和定义分开,从而实现了数据隐藏,数据隐藏也是一种封装。
在类声明部分直接定义函数的,编译器会把这个函数当作inline函数来处理。
c++类中默认提供的成员函数有:
1.默认构造函数,如果没有定义。
2.默认析构函数,如果没有定义。
3.拷贝构造函数,如果没有定义。
4.赋值运算符,如果没有定义。
5.地址运算符,如果没有定义。
下面对上述5个函数的说明:
1.创建对象或者使用new为指向类的指针分配了内存空间,系统就会自动调用默认构造函数。如果定义了构造函数,c++不会定义默认的构造函数。
带参数的构造函数也可以是默认构造函数,只要所有的参数都有默认值。如:Klun(int x=1;double y=12.3){return x*y}。但是默认的构造函数只能有一个,若此时再定义一个无参的构造函数,Klun(){}就会产生二义性。如:Klun k;在声明这个类的对象k时,系统不知道是调用哪个构造函数。
2.在一个类中析构函数只能有一个,这里就不说了。有一点要提醒,当构造函数使用new来分配内存时,析构函数的delete形式要与new的形式一致。
3.拷贝构造函数,在三种情形下会调用:
a、将一个对象初始化另一个新创建的对象时(这里有新对象产生)
b、对象作为函数的实参传递给函数的值形式参数时
c、对象作为函数返回值时
默认的拷贝构造函数的功能是实现对象值的拷贝。(浅拷贝),只进行值拷贝,地址没有进行拷贝。
(深拷贝),值和地址都进行了拷贝。
4.赋值运算符是在将已有的对象赋给另一个对象时会自动调用。(没有新对象产生)。

运算符重载:
不能重载的运算符有:
sizeof sizeof运算符
. 和.成员运算符(两个)
:: 作用域运算符
?: 条件运算符
const_cast 、dynamic_cast、reinterpret_cast、static_cast强制类型转换运算符。
只能通过成员函数重载的运算符有:
= 赋值运算符
() 函数调用运算符
[] 下标运算符
-> 通过指针访问类成员的运算符
函数返回(对象、引用)的问题:
如果函数要返回的是局部对象,则应返回对象,而不是引用。在这种情况下,将使用拷贝构造函数来生成返回的对象。
如果函数要返回一个没有公有拷贝构造函数的类对象,则应该返回一个指向该对象的引用。(运算符重载函数一般这么做)
在返回对象和引用都可行的时候,应该返回引用。
静态类成员函数与静态变量
静态变量不能在类声明部分作初始化,除非是const静态变量,它在类中声明,类外初始化,如: class A{static int x;};int A::x=1024;且在类外初始化的时候不要static关键字(同friend声明要,定义不要friend,而且也不需要类名,返回类型 函数名(){})。
静态成员函数只能使用静态数据成员,不能使用类成员,只能访问静态成员,它的定义为:返回类型 类名::函数名(){}(同friend声明要,定义不要friend)。
关于继承与多态的问题
需要重新定义的函数应该在基类中声明为虚函数。
构造函数和友元函数不能为虚函数(非成员函数都不能是虚函数),但
基类*的析构函数要为虚函数(这里是基类)。
1、如果函数是通过引用或者指针而不是对象的方式调用,分两种情况:(在函数是通过指针或者引用的方式调用时)a、如果该函数不是虚函数,程序将根据引用或者指针的类型来确定调用的函数,如,Base b1; Drived d1; Base &t=d1; //这里t的类型为Base型,故调用Base的函数。b、如果该函数是虚函数,则根据指针或者引用所指的对象类型来确定调用的函数,如,在上面的栗子中,t所指对象(d1)的类型为Drived型,故调用的是Drived的函数。
2、如果函数是通过对象的方式调用函数,不管基类有没有,调用的都是对象的类型所指的函数,如,Base b1; Drived d1=b1; d1调用的是(d1的类型为Drived)Drived的函数;
基类的指针或者引用指向派生类来调用基类或者派生类函数是一种常见的实现多态的方式。
关于程序异常的问题:
调用abort()函数,位于头文件cstdlib中,其典型的实现是向标准错误流(即cerr使用的错误流)发送消息abnormal program termination(程序异常终止),然后终止程序。abort()是否刷新缓冲区取决于实现,也可以用exit(),该函数刷新文件缓冲区,但不显示消息。
hmean()返回错误码。
throw关键字表示引发异常,其后指出异常的特征,它是一个跳转语句。
catch关键字表示捕获异常。
try块标识其中特定的异常可能被激活的代码块,常与catch连用。
noexcept关键字(c++11)用在函数后面,如,double mam()noexcept;表示此函数不会引发异常。
string类输入的方式:
1、char buf[1024]; cin>>buf; //输入一个单词; cin.getline(buf,1024); //输入一行,舍弃换行符。 cin.get(buf,1024); //输入一行,将换行符留在输入队列中。
2、string str; cin>>str; //输入一个单词; getline(cin,str); //输入一行,舍弃换行符。 getline(str,’\n’); //输入一行,已换行符结束。

10-07 16:03