多文件链接
- 命令行
- make的使用
变量定义
- auto的使用 相关学习网址
- 机理:根据后面的赋值,推测变量类型
- 作用:简化变量初始化的书写,例如迭代器
- 注意:
- 变量必须初始化(即赋值)
- auto是占位符,不可用于类型转换,例sizeof和typeid
- 同一个auto里面只能定义一种类型
auto x1 = 5, x2 = 5.0, x3='r';// This is too much....we cannot combine like this
- 指针 new/delete 相关学习网址
- 这两个操作与sizeof一样不是函数
- 与malloc的区别:malloc不可用于初始化
- 例:
int *a1=new int; int *a2=new int[10]; delete a1; delete[]a2;
- 左值引用 相关学习网址
- 格式:
int v0; int &v1=v0;
- 前提:旧变量已经占有内空间,即右侧值能够取地址,若无法取地址,则用常引用
const int &t=10; //相当于 const int temp=10; const int &t=temp; //const 使得temp指向的地址只可存为10这个值,只可读,不可改变
- 作用:可使得多层嵌套时,方便阅读,例用于结构变量
int t=a.b.c; //等价于 int &temp=a.b; int t=temp.c;
- 注:函数的返回值可以是引用类型,但不可是函数临时变量
- 右值引用 相关学习网址
- 特点:不可取地址、没有名字的就是右值
- 格式:
int && sum=3+4; float && res=ReturnValue(f1,f2);//将函数的返回值保存下来 void ReturnValue(T && s,T && t){...}
- 作用:减少临时变量拷贝的开销
变量的初始化、类型的推导、基于范围的for循环
- 初始化列表
int a[]={1,2,3}; //等价于 int a[]{1,2,3};//列表的初始化中,花括号前的等号可省略
- 初始化变量
int a=3+5; int a={3+5}; int a(3+5); int a{3+5}; int *i=new int(10);//i指向的内存中有个初始值10 double *q=new double{1.2f};
- 变量类型的推导
struct{char *name;} anon_u; struct{int d;decltype(anon_u)id;} anon_s[100];//匿名的struct数组 int main{ decltype(anon_s)as; cin>>as[0].id.name; ... } //decltype的用法:https://blog.csdn.net/u014609638/article/details/106987131/
- 基于范围的for循环
int arr[]={1,2,3}; for(auto e:arr) cout<<e<<endl;
函数的重载
-
注意:保证各个函数的参数不同
-
例:
void print(int a){ cout<<a<<endl; } void print(string str){ cout<<str<<endl; }
函数参数的缺省值与追踪返回类型的函数
- 函数参数的缺省值
-
适用情形:函数参数一般有一个固定值
-
注:只可放在函数的最后几个参数(若有n个参数,k个可直接赋值,则第n-k+1~n个参数是直接赋值的)
-
例:
void print(char* msg = "hello"){ cout<<msg<<'#'; } int main(){ print("Berjing..."); print(); return 0; } //输出Beijing。。。#hello#
- 追踪返回类型的函数
-
普通声明:
int func(char *ptr,int val);
-
追踪返回类型的函数声明:
auto func(char *ptr,int val) -> int; auto func(char *ptr,int val);//这种写法的正确性有待指正
-
作用:若函数返回值未知,且需根据函数参数推导,则可使用这种写法
template<typename T1, typename T2> auto Sum(T1&t1, T2& t2) -> decltype(t1+t2){ return t1+t2; }
类的定义
-
自定义类型,包含函数与数据
-
类中函数——成员函数
-
类中成员——数据成员
-
类的成员(数据、函数)可拥有不同的访问权限
-
权限种类:public、private、protected
- 访问权限
class Matrix{ public: void fill{char dir); private: int data[6][6]; }; class Matrix{ int data[6][6]; public: void fill{char dir); };
-
对象:用类定义的变量
-
调用形式:对象名.成员名(仅限public)
-
类外定义成员函数时,要加类名限定,格式:类名::函数名( :: 域运算符)
-
成员函数的两种定义:
//(1)在类内定义成员函数 Class Matrix{ Public: void fill(char dir){ …; } }; //(2)在类外定义成员函数 Void Matrix::fill(char dir){ …; };
-
类中默认一个指针this(编译器产生),指向本身对象存放的地址,用”->”访问
-
友元函数:
- 可访问类的private成员
- 特点:
- 会破坏封装性
- 与声明位置无关
- 类型:friend 函数原型;
构造函数
- 默认构造函数(无参数)
- 在定义元素为对象的数组时(ClassName array_var[NUM];),类必须声明默认构造函数的定义,即在类里必须写上ClassName(){…;}(省略号中内容可有可无)
- 使用默认构造函数(无参)生成对象时,格式:ClassName 变量;(变量后不可有括号)
- 还可以通过ClassName()=default;来构造
- 构造函数
- 可使用初始化列表初始化成员数据 相关学习网址
-
形式:以冒号开头,后跟一系列以逗号分隔的初始化字段,每个数据成员后跟一个放括号中的初始化式
Class ClassName{ public: int a; string b; ClassName():a(0),b("aba") {}//这个大括号不可以忘 //上下两种实质上等价 ClassName(){ a=0; b{"aba"}; } };
-
委派构造函数:可调用其他构造函数
class Info{ public: Info(){Init();} Info(int i):Info(){id=i;} Info(char c):Info(){gender=c;} private: void Init(){...;} int id {2016}; char gender{'M'}; ...; };
-
析构函数:一种成员函数
-
形式:~ClassName();
-
特点:
- 没有函数返回值
- 没有参数
- 一个类只有一个析构函数
- 若不写则系统默认生成
-
调用时间及对象:编译器在对象生命期结束时自动调用
-
作用:释放占用资源,或其他后期处理
class String{ private: char* p; public: String(int n); ~String(); } String::~String(){ delete[]p; } String::String(int n){ p=new char[n]; }
- 拷贝构造函数:一种特殊的构造函数
-
用于初始化,以自身类类型的常量引用作为第一个参数,而编译器会根据这个自动拷贝生成一个新对象,且其额外参数都有默认值
class Person{ int id; ...; public: Person(const Person& src){id=src.id;...;} ...; };
运算符重载
- 赋值运算符重载:一种特殊成员函数 相关学习网址
-
实现
ClassName& operator= (const ClassNAme& right){ if(this != &right){//避免自己赋值给自己 //将right对象中的内容复制到当前对象中 *this; }
-
函数名:operator=
-
参数:right,即等号右侧的变量的常量引用(常量:防止函数对right进行改变;引用:避免函数调用时对实参的拷贝,提高了效率)
-
返回值:ClassName&(*this),也是引用,理由如上,并且可实现连续赋值(a=b=c)
-
注意:
ClassName class1; class1=class2; //该情况下,第一句调用无参的构造函数,第二句则调用了拷贝赋值运算符重载函数 ClassName class1=class2; //用2给1赋值,调用了拷贝构造函数
- 流运算符的重载
-
作用:重载对象的输入输出
-
声明
Class Test:id(4); istream& operator>> (istream& in,Test& dst){ in>>dst.id;//id为Test类的对象dst的一个成员变量 return in;//为了使得一个cin能输入多个数据,即cin>>a>>b; } ostream& operator<< (ostream& out,const Test& src);//同上
- 函数名:operator>>和operator<<
- 返回值:istream& 和 ostream& ,均为引用
- 参数:流对象的引用,目标对象的常量引用。
-
提示: 若在该类中,定义一个另外一个类定义的对象(ClassName C;)且另外一个类中未定义输入输出流,则可能会出现错误
- 函数运算符的重载
-
声明:
ReturnType operator()(Paramenters){//函数在声明时可以只写类型 ...; return ElemType; } ClassName Obj; ElemType t=Obj(real_parameters);//Obj.operator()(real_parameters);
-
作用:使得一个对象可以被直接调用,动态改变函数作用(例:一个比较大小的函数,可以利用这种方式,动态改变与哪个数作比较,从而得到结果)
- 下标运算符的重载
-
声明:
ReturnType operator[](Paramenters);
-
若返回类型是引用,则可放等号左侧,即接受赋值(Obj[index]=value);若返回类型不是引用,则只可放括号右侧(value=Obj[index])
-
作用:增强功能,使得以字符串等做下标也可能实现(类似stl中的map)
- 自增自减符的重载
-
声明
//前缀运算符的重载 ReturnType operator++(); ReturnType operator--(); //后缀运算符的重载 ReturnType operator++(int dummy); ReturnType operator--(int dummy);//dummy表示哑原文函数,为了区分前后函数,但无实质作用
成员函数 相关学习链接
- 静态成员
- 常成员
继承:在已有类的基础上产生新的类
- 继承
-
常见继承方式:public,private
-
private
class Derived:[private] Base{...};//缺省继承方式为private继承,[]表示里面内容可写可不写
-
public
class Derived:public Base{...};
- 基类(父类,base class):其中被继承的已有类
- 派生类(子类,扩展类,derived class):继承得到的新类
using Base::Base;//以此来继承基类构造函数
-
-
注意:
- 基类构造函数的默认值不会被派生类继承,但基类构造函数可以继承
- 若基类的某构造函数被声明为私有成员函数,则派生类中无法声明与继承该构造函数
- 若派生类使用了基类中的构造函数,则编译器不会再为派生类生成默认构造函数
- 函数重写:基类中已定义好的成员函数,在派生类中重新定义
- 注意:若进行函数重写,则会屏蔽基类中其他同名的成员函数
- 虚函数
-
向上映射:派生类对象转基类对象
- 特点
- 编译器可自动完成
- 一种隐式自动类型转换
- 凡是接受基类对象的地方(函数参数),都可使用派生类对象,编译器会对派生类对象进行自动类型转换
- 特点
-
向下映射:基类对象转派生类对象
-
多态 学习相关链接
- 分类:静态多态、动态多态
- 静态多态:一种在编译期间就会完成的,根据参数选择合适的函数
- 动态多态:一种在程序运行时,根据基类的引用(指针)指向的对象来确定自己调用哪个类的虚函数
- 条件
- 基类中必包含虚函数,且派生类中一定要对积累虚函数进行重写
- 通过基类对象的指针或引用调用虚函数
- 条件
- 分类:静态多态、动态多态
-
虚函数: 学习相关链接
-
条件:参数是基类的引用且引用了虚函数
-
final
-
作用:阻断某函数的继承
-
格式
ReturnType print() final;//后续子类均不可重写该函数
-
-
纯虚函数
- 在虚函数的形参列表后加上=0
- 作用:只可作为声明做虚类
- 包含该函数的类则称为抽象类(接口类),不可实例化
-
类型转换
- 自动类型转换:可隐式自动进行,不需人工干预 相关学习链接
-
非自定义
-
整型:
int -> unsigned int -> long -> unsigned long -> long long ->unsigned long long
-
浮点型
float -> double
-
其他情况
-
操作数中无浮点数
当char、unsigned char、short、unsigned short出现在表达式,一般将其自动转为int,特殊情况下,unsigned short 也可能转换成 unsigned int。
-
橾作数中有浮点型数据
所有操作数都将转换为 double 型。
-
赋值运算符两侧不对称
将右值类型可能提升或降低为左值类型。
-
右值超出左值类型范围时
结果无意义。
-
-
-
自定义:只可对类进行操作,需借助转换构造函数