1.函数的分文件编写:
.h的头文件(写函数声明) .cpp的源文件(写函数功能实现)
2.空指针和野指针 :
0-255的内存是系统所占有的 `int *p=(int *)0x1001` //是一种错误
3.常量指针:
`const int *p=&a` //a不可以改变,p可以改变
4.指针常量:
`int * const p=&a ` //a可以改变,p不可以改变
5.结构体数组:
`struct student arr[3]{}`
6.函数形参用const修饰,可防止在函数中对实参误 *** 作
7.堆区的开辟和释放:new和delete
int *p=new int(6);
delete p;
int *q=new int[6];
delete[] q; //数组delete要加[]
8.引用:
给变量取别名
int a=6;
int &b=a; //a和b同时指向6所在地址空间
引用必须初始化,且初始化后不可更改
函数返回值不可以是 局部变量 、引用类数据, 可以用static全局变量引用类数据
引用本质是一个指针常量
常量引用:用来修饰形参,防止误 *** 作
函数形参可以有默认值,若调用传入自己的值,则用传入的值,否则用默认值
从第一个有默认值的形参开始,后面所有的参数都要有默认值
函数声明中有默认值后,函数实现里不可以有默认值参数
10.函数重载:1.遇到常量引用时 2.遇到默认参数值时
二、类和对象1.类中成员的访问权限:
public protected private
struct默认权限是公共,class默认权限是私有
构造函数语法:类名(){函数体}
析构函数语法:~类名(){函数体}
普通构造函数
拷贝构造函数:`Person(const Person &p){ name=p.name; }`
调用拷贝构造函数的三种情况:
1.使用一个创建完成的对象创建一个新的对象
2.值传递的方式给函数参数传值(形参是一个对象值时,实参传入时会拷贝一个副本,即创建一个新的对象,使用拷贝构造函数)
3.以值方式返回局部对象(函数返回类型是一个类,在调用这个函数,将该函数返回值赋值给另一个对象时,会创建一个新的对象,使用拷贝构造函数)
匿名对象: `Person();`匿名对象被创建后会被系统立刻回收
编译器提供的默认函数: 默认无参构造函数、析构函数、拷贝构造函数
规则:若定义有参构造,则不提供默认无参构造,但提供拷贝构造 若定义拷贝构造,则不提供其他构造
浅拷贝:简单的等号赋值
深拷贝:另外开辟一块空间进行拷贝赋值
创建对象时若有申请空间,使用完后需释放堆区空间,在使用拷贝构造时,若使用浅拷贝,则会有重复释放的问题,此时需要用深拷贝(在析构函数中释放)
Person(int a,int b,int c):pA(a),pB(b),pC(c){}
初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内进行赋值 *** 作
必须使用初始化的几种情况:
常量成员: 因为常量只能初始化不能赋值,所以必须放在初始化列表里面
引用类型: 引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
没有默认构造函数的类类型: 因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。
创建时先构造成员对象,析构时先析构本类
6.static关键字:1.所有对象共享 2.编译阶段分配内存 3.类内声明,类外初始化
class Person{
public:
static int age;
}
int Person::age=3; //类外初始化
静态成员函数:只能访问静态成员变量
一个空对象占用一个字节内存(每个空对象都应有一个独一无二的地址空间)
只有非静态成员变量才属于类的对象(成员变量和成员函数分开存放)
1.解决名称冲突
2.返回对象本身用*this (this指向被调用函数所属的对象)
8.const关键字:在成员函数后加const(常函数),修饰的是this指向,函数内部this所指向的值不可被修改(可加mutable使仍可以修改)
常对象:只可以调用常函数
全局函数/类/其他类的成员函数前加friend关键字(写进类中),则该函数可以访问类中的private变量
10.运算符重载:class person{
public:
int a;
int b;
}
加运算符重载方法:
//1.成员函数重载
person operator+(person &p){ //在类内
person tmp;
tmp.a=this.a+p->a;
tmp.b=this.b+p->b;
return tmp;
}
//2.全局函数重载
person operator+(person &p1,person &p2){ //在类外
person tmp;
tmp.a=p1->a+p2->a;
tmp.b=p1->b+p2->b;
return tmp;
}
//这些重载函数可以函数重载,即函数参数类型可以改变
左移运算符重载:
//只能用全局函数实现
ostream & operator<<(ostream &cout,person &p){
cout<
++运算符重载:
//成员函数实现 前置++:
myinteger& operator++(){ //返回类型为指针
num++;
return *this;
}
//后置++:
myinteger operator++(int){ //int 为占位参数, 返回类型为值而不是指针,因为tmp是个局部对象
myinteger tmp=*this;
num++;
return tmp;
}
11.继承:
语法:
class 子类 : 继承方式 父类
继承方式:公共继承、保护继承、私有继承
父类的非静态成员属性都会被子类继承
子类父类构造和析构的顺序
继承中父类和子类同名时的访问问题:访问父类时要加作用域,如果子类中有和父类重名的成员函数,子类的同名函数会隐藏掉所有的父类同名函数
菱形继承,要用virtual虚继承解决,父类继承基类时加virtual
动态:父类中的函数写为virtual虚函数,子类重写该虚函数
纯虚函数:
virtual 返回值类型 函数名 (参数)=0;
当类中有了纯虚函数,这个类也叫作抽象类
虚析构/纯虚析构:
解决父类指针释放子类对象问题(父类指针指向子类对象若无虚析构,析构时不会调用子类的析构函数,而只会析构父类) 用virtual修饰父类的析构函数
三、文件 *** 作:
头文件:
三大文件 *** 作类型:写:ofstream 读:ifstream 读写:fstream
文件打开方式:ios::in ; ios::out ; ios::binary
例子:写文件:
ofstream ofs; ofs.open(“文件名”,打开方式);
ofs<<"xiewenjian<
四、模板:
语法:
template void myswap(T &a,T &b){}
使用方式:
1.自动类型推导 `myswap(1,2);` 不会发生隐式类型转换 或:
2.显示指定类型 'myswap
模板必须要确定T的数据类型才可以使用
ps:隐式类型转换举例:int和其他类型数据运算,其他类型隐式转换为int
模板和普通函数的调用规则:
1.普通函数和模板都可调用时,优先普通函数
2.可使用空参数列表模板强制调用模板`myswap<>(1,2);`
3.模板也可以重载
4.如果模板更好的匹配,优先模板 模板具有局限性,可以用函数模板重载方法,将模板参数具体化,会优先调用参数具体化的模板
template <> bool mycompare(person &p1,person &p2){};
类模板:
template class person{
person(nametype name,agetype age){}
}
person p("yxh",2);
1.类模板没有自动类型推导
2.类模板参数列表可以有默认参数
template
普通类的成员函数一开始就可以被创建(定义时) 类模板的成员函数只有在调用时才会被创建
类模板作函数参数三种方式:
1.指定参数类型
void printperson( person{} )
2.参数模板化
template void printperson(person){}
//查看某个类型的名字:`typeid(nametype).name()`
3.整个参数模板化
template void printperson(T &p){}
类模板与继承:
如果父类是类模板,子类需要指定父类的T的类型,或者,子类也成为一个类模板
类模板成员函数类外实现:
template
person::person(nametype name,agetype age){}
类模板分文件编写:
由于类模板的成员函数是在调用时才创建,只包含头文件h而不包含源文件cpp时,不 可行,解决办法:1.直接包含cpp文件,2.将h和cpp内容写到一起,命名为hpp文件,包含hpp文件
五、stl(标准模板库):
stl广义上分为:容器(序列式容器、关联式容器)、算法(质变算法、非质变算法)、迭代器 //(还有仿函数、适配器、空间配置器)
容器和算法通过迭代器链接,每个容器都有自己的迭代器,算法通过迭代器访问容器中的数据
1.string容器:
string字符串拼接:
string& operator+=(const char* str);
string& operator+=(const char ch);
string& operator+=(const string& str);
string& append(const char* str);
string& append(const char* str,int n);
string& append(const string &str);
string& append(const string &str,int pos,int n);
string字符串查找:
int find(const string& str,int pos);
int find(const char* str,int pos);
int find(const char* str,int pos,int n);
int find(char c,int pos); //查找第一个位置,rfind用于查找最后一个位置
string字符串替换:
string& replace(int pos,int n,const string& str);
string& replace(int pos,int n,const char* str);
string字符串比较:
int compare(const string& str);
int compare(const char* str);
string字符串获取:
char& at(int n);
string字符串插入:
string& insert(int pos,const char* str);
string& insert(int pos,const string& str);
string& insert(int pos,int n,char c);
string字符串删除:
string& erase(int pos,int n);
string获取子串:
string& substr(int pos,int n);
2.vector容器
vector构造函数:
vector v;
vector(v1.begin(),v1.end());
vector(n,elem);
vector(const vector &v1);
vector赋值 *** 作:
assign(v1.begin(),v1.end());
assign(int n,elem e);
vector容量 *** 作:
v.empty();
v.size();
v.capacity();
v.resize(int n);
v.resize(int n,elem e);
vector通过迭代器删除:
v.insert(const_iterator pos,elem e);
v.insert(const_iterator pos,int num,elem e);
v.erase(const_iterator pos);
v.erase(const_iterator begin,const_iterator end);
v.clear();
vector取数据:
v.front();
v.back();
vector交换两个容器的数据:
v.swap(v1)
vector(v).swap(v); //可利用swap和匿名对象减小空间浪费
//vector预留空间:
reserve(int n) //预留位置不初始化不可访问
3.deque容器
deque: vector单端数组,deque双端数组,vector头部插入删除效率低,deque访问速度慢,deque无capacity接口,没有容量概念
deque排序:`sort(begin(),end());` //sort算法,对于支持随机访问的迭代器的容器,都可以用sort排序
list:迭代器不支持随机访问,是一个双向迭代器,也不可用[]和at访问元素
翻转:reverse()、排序sort() //两个都是成员函数
特点:插入时会自动排序,属于关联式容器,底层结构是二叉树,set不允许有重复元素,multiset允许
删除的重载:erase(elem e);
查找:find(elem e);//若存在,则返回该元素的迭代器,否则返回end()
统计:count(elem e);
插入只有insert();
set内置数据类型时有默认排序规则,也可通过仿函数修改规则,但自定义类型必须先指定排序规则,否则无法插入
pair对组:成对出现的数据,利用对组可以返回两个数据
创建方式:
pair p(value1,value2);
pair p=make_pair(value1,value2)
//利用first和second取数据
7.map/multimap:
map中所有元素为pair类型,pair第一个数据为key值,起索引作用,第二个为value值,所有元素按照key值自动排序,属于关联式容器,底层结构是二叉树
map m;
m.insert(pair)(type1value,type2value)) m.insert(make_pair(type1value,type2value))
//可用[]访问元素:m[key]=value
六、函数对象:
重载函数调用符()的类,其对象称为函数对象
函数对象在使用时,可以像普通函数那样,有参数,有返回值
函数对象可以有自己的状态,可以作为参数进行传递
返回bool类型的仿函数称为:谓词
搬运算法:transform(v1.begin,v1.end,v.begin) //搬运前需要开辟空间
遍历算法:for_each(v1.begin,v1.end,fun)
常用查找算法:find、find_if、adjacent_find、binary_search、count、count_if
常用排序算法:sort、random_shuffle、merge、reverse
常用拷贝和替换算法:copy、replace、replace_if、swap
常用算术生成算法:fill、accumulate //include
常用集合算法:set_intersection、set_uniom、set_difference
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)