全局变量自动初始化为0.局部变量初值随机
用new声明类时,()会初始化类内变量
类的初始化时,参数列表的实参为最终值,优先级高于函数体中定义的初始值
对象数组声明时,默认执行对象类的无参构造函数
在Class C = object 或 Class C[3] ={object1,object2,object3}时,并不是引用的传递,而是作为复制构造函数的参数来进行初始化
因为Class C = object <=> Class C(object) 即复制构造
复制构造函数,即使用复制的方式生成一个类的对象
全局变量可在全局访问,静态全局变量只能在其所处文件访问
静态变量具有全局的生命周期,所以存在于全局数据区,所以像全局变量一样默认初始化为0
因为类内不能用=给变量初始化赋值,所以要在类外给静态变量赋值
消亡顺序:普通->函数内静态变量->主函数内静态->主函数结束->全局变量->程序结束
常量对象只可以调用常量方法,常量、普通重载根据对象是否常量来调用
类的常量变量只能通过参数列表初始化
友元函数放在public,private等都是一样的
友元类是单向、不传递的
myComplex operator-(double r);
//只能重载myComplex - double的操作
friend myComplex operator-(const myComplex &c1,double r);
friend myComplex operator-(double r,const myComplex &c1);
//重载myComplex - double和double - myComplex
为了=操作符重载后能res=a=b;这样连续使用,重载函数应返回引用
流操作运算符的重载可分为友元和成员
友元:
friend ostream & operator <<(ostream & output,myComplex & c)
{
output<
成员:
ostream & operator <<(ostream & output)
{
output<
如果像上面那样要操作c.私有属性,则只有<<可以声明为成员函数,因为<<是把私有属性读取,而>>是设置私有属性
自增自减运算符的重载
++i返回自身的引用 i++返回自身的复制
++(int) int在后面 表示后置++ 即i++
派生类中指定访问基类的同名变量,要BaseClass::value
基类A通过友元可以被基类B访问私有变量,则基类B的派生类可以访问A,且B不能访问A的派生的私有变量
如果派生类声明了与基类同名但是参数表不同的函数,还是会隐藏基类的同名函数
如:
s2.CStudent::PrintInfo();
派生类是多重继承时,基类初始化顺序从左向右
派生类的复制构造函数 B(const B & b):A::A(v),f(b.f) {}
若派生类复制构造时没有调用基类的复制构造函数,则调用基类的构造函数
pBase2 = (Derived*)pBase1;
除非pBase1本来就指向Derived类对象,这样才是安全的,否则容易出错。
virtual只要写在类内
virtual只能配合 基类指针 和 基类引用(因为C++中类的赋值是传值而不是引用)实现多态
若基类BaseFunc1调用虚函数Func2,派生类又重写了虚函数Func2,此时基类指针调用BaseFunc1时Func2是派生类的
因为基类构造时派生类还不存在,基类析构时派生类已经消亡,所以此时在构造函数或析构函数时调用的虚函数不是多态的
若类A的func1不是虚函数,继承A的B的func1是虚函数,C继承B
A * pa=&c;
B* pb = &c;
则pa->func1不是多态,pb->func1是多态
delete掉基类指针,只会调用基类的析构函数,不会涉及到派生类。所以需要虚析构函数
纯虚函数:=0,即把函数体换成=0
抽象类:包含纯虚函数的类
虚基类:
class B : virtual public A
防止共同的基类造成二义性
cout重定向:
freopen("test.txt","w",stdout);
cin重定向:
freopen("text.txt","r",stdin);
cin.eof(); //是否结束
//Ctrl+Z 结束输入
cin.clear(); //将状态恢复正常
默认格式
类型 输入 输出
整数 int int
带小数点 float float或指数,根据长度选择
char char char
char* 字符序列 字符序列
void* 无前缀十六进制 无前缀十六进制
bool true/1;false/0 0/1
iostream的流操纵符
endl 本行结束换行
ends 一个string结束,加空格
flush 清空缓冲区
oct,dec,hex 八位,十位,十六位
ws 过滤空白字符
iomanip的流操纵符
小数:fixed 普通 scientific 科学计数法
小数的精度:setprecision(int) fixed或scientific时指小数点的位数,否则为有效位数
对齐: left right
进制:setbase(int)
宽度:setw(int) 一次有效 setfill(int c)不足用ASCII码为c的字符填充 intrnal正负号左右对齐,中间填充
boolalpha true/false noboolaplha 1/0
showbase noshowbase 是否输入数值进制的前缀
showpoint noshowpoint 是否在整数时也显示小数点
showpos noshowpos 正数是否显示+
skipws noskipws 是否跳过ws
uppercase no upercase 十六进制ae还是AE,科学计数法的e还是E
cin.get()
cin.get()!=EOF
cin.peek()
查看一个字符,但不从流中取出
cin.getline(char buf[10],10)
会在末尾加上'\0' 所以最多9个字符
cin.eof()
cin.ignore(10,':')
跳过10个字符或’:‘之前的字符,无参数时跳过一个字符
打开文件
ifstream inFile;inFile.open("data.txt",ios::in);
//或 ifstream inFile("data.txt",ios::in);
//文件是否存在
if(inFile){}
文件的写入
outFile<>data>>data;
关闭文件
inFile.close();
读取多行文本时判定一行结束
while((ch=inFile.get())!=EOF)//文件是否结束
{
if(ch=='\n')
{
//一行结束
}
}
二进制打开文件
ofstream outFile("data.txt".ios::out|ios::binary);
二进制写入
outFile.write((char *)&stu,sizeof(stu));
二进制追加
因为ios::out打开时会清除数据,所以要用ios::app,它会在数据末尾写入数据
ofstream outFile("data.txt".ios::app|ios::binary);
二进制读取
while(inFile.read((char *)&stu,sizeof(stu)))//读到文件结束
{
cout<
put(),get() 读写
while(inFile.get(c))//c为字符
{
outFile.put(c);
}
用get()读到数组
inFile.get(char* array,int length,char delim='\n');
随机读
inFile.seekg(20);//读指针位置为20
inFile.seekg(20,ios::beg);//位置为beg+20
//ios::beg 开始 ios::cur 当前 ios::end 结尾
inFile.tellg();// 返回指针当前位置
随机写
seekp()
,tellp()
用法与随机读一样
用while(inFile.read)
读取文件结束后,要用inFile.clear()
恢复流的状态,才能继续操作
函数模板
template
T abs(T x)
{
return x<0?-x:x;
}
typename和class是等价的,但class容易与类混肴,所以用typename
模板函数编译时不会生成代码,使用时才生成具体函数
应该连同函数体放在头文件
模板函数重载
template
T abs(T1 x,T2 y)
{
}
abs(T x)与abs(T1 x,T2 y)重载
类内的函数与静态变量
template
class MyClass
{
public:
static T x;
void func(T y);
}
template
void MyClass::func(T y)
{
}
template
T MyClass::x = 初始值;
模板的继承
class B:public A//B是普通类,所以A必须指定类型,这样继承后的B还是普通类
template
class B:public A{}
template
class B:public A{}
template
class B:public A{}
{
T t;
}