一、引用
1.引用基本语法
数据类型 &别名 = 原名
int& b = a;//创建引用
2.引用注意的事项
//引用必须初始化
int a = 10;
int& b = a;//必须要有这个a
//引用一旦初始化之后就不可以更改了 &b指向了a 就不能在指向c
//可以赋值
b = 20;
3.引用做函数
void swap13(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}引用会修改实参
4.引用做函数返回值
引用不可以返回局部变量
引用返回值可以作为左值被赋值
引用的本质就是指针常量
5.常量引用
void showValue(const int& val)
{
//val = 100;//不可以修改
cout << val << endl;
}
修饰形防止误操作
二、函数
1.占位参数
占位参数也可以有默认值
void fucnnc(int a, int = 10)
{
cout << "占位参数" << endl;
}
2.函数默认参数
int xingcan(int a, int b = 10, int c = 20)//b有参数的话C就也要有参数 实参后于形参
{
return a + b + c;
}
//声明和实现只能有一个有默认参数、谁有都行
3. 函数重载
函数重载 函数参数类型不同 或者个数不同 或者 顺序不同
4.函数重载注意事项
用重载的时候尽量不要用 默认值
三、类
1.封装
1.1属性和行为作为整理
class circle
{
//1.访问权限
public:
//2.属性
int r;
//3.行为 函数
double jisuan()
{
return 2 * PI * r;
}
};
1.2封装的访问权限
//类的权限 struct和class
//struct 不写任何访问权限的话是公用的
//class 不写任何访问权限的话是私有的
//访问权限
//公共权限 public
//保护权限 protected 类内可访问 外不可以 儿子可以访问父亲私有的保护内容
//私有权限 private 类内可访问 外不可以 儿子不可以访问父亲的私有内容
1.3类在头文件源文件写法
头文件类似于接口的写法
源文件类似于实现接口的类的写法
2.对象特性
01构造函数和析构函数
lianxi()
{
cout << "调用类之后会调用构造函数" << endl;
}
~lianxi()
{
cout << "这个类执行完会后会调用析构函数" << endl;
}
02构造函数的分类及调用
构造函数分类: 无参构造 有参构造 普通构造 拷贝构造
gouzao()
{
cout << "无参构造" << endl;
}
gouzao(int a)
{
age = a;
cout << "有参构造" << endl;
}
gouzao(const gouzao& g)//拷贝构造函数的套路
{
age = g.age;
cout << "拷贝构造" << endl;
}
~gouzao()
{
cout << "析构函数" << endl;
}
//调用
//1.括号法
gouzao g1;//默认构造函数调用
gouzao g2(10);//有参构造函数
gouzao g3(g2);//拷贝构造函数
//注意事项
//调用默认构造函数的时候不要带括号()
cout << g2._age() << endl;
cout << g3._age() << endl;
//2.显示法
gouzao g11;
gouzao g12 = gouzao(10);//有参构造 等号右侧是匿名对象 就是没有名字 等号左面给他赋予了名字
gouzao g13 = gouzao(g12);//拷贝构造
//注意事项
//不要利用拷贝构造函数 初始化匿名对象 gouzao(g3)
//3.隐式转换法
gouzao g4 = 10;//相当于写了 gouzao g4 = gouzao(10);
gouzao g5 = g4;//相当于写了 gouzao g5 = gouzao(g4);
03拷贝构造函数调用时机
//1.使用一个已经创建完毕的对象来初始化一个新对象
void ceshi1()
{
gouzai g1(20);
gouzai g2(g1);
cout << g2._age() << endl;
}
//2.值传递的方式给函数参数传值
void doWork(gouzai g)//这里要注意形参传递的过程就相当于拷贝构造函数了 所以调用ceshi2的时候会出现调用拷贝构造函数
{
}
//3.值方式返回局部对象
gouzai doWork3()
{
gouzai g;
return g;
}
04构造函数调用规则
//默认会给出至少三个函数
//1.默认构造 默认析构 默认拷贝
//2.定义有参构造 C++就不会提供默认无参构造 但会提供拷贝构造
//3.定义拷贝 C++就不会提供其他构造函数
//不会提供 不代表 不可以自己写
05深拷贝与浅拷贝
浅拷贝就是编译器自动编译的拷贝,深拷贝就是自己编写的拷贝
浅拷贝容易出现堆数据重复释放,解决方法:创建一个深拷贝
在深拷贝函数里创建一个新的堆区数据Height = new int(*g.Height);//正确应该这么写 新开辟一个堆区 而不是上面那种直接编译器写
06初始化列表
public :
int a;
int b;
int c;
Person(int ga, int gb, int gc) :a(ga), b(gb), c(gc)
{
//以上就是初始化的结构 操作套路
}
07类对象作为类成员
其他类对象作为本类成员,构造是先构造对象再构造自身,析构的顺序与构造相反
08静态成员
class jingtai
{
public:
static void func333()
{
A = 100;//静态的变量可以修改
//B = 200;//不可以 因为不是静态的
cout << "jingtai" << endl;
}
static int A;//静态成员变量
//int B;
};
int jingtai::A = 0;//静态成员变量 类内声明类外初始化
void test222()
{
//1.通过对象访问
jingtai j;
j.func333();
//2.通过类名访问
jingtai::func333();
}
09变量
//空的类占用一个字节 一个int就占用四个字节
class chengyuan
{
int a;//费静态成员变量 属于类的对象上 四个字节 这个类就占用四个字节
static int b;//静态成员变量 不属于类对象上
void fumc(){}//非静态成员函数 不属于类对象上
static void fun(){}//静态成员函数 不属于类的对象上
};
10this指针
//1.解决名称冲突
//2.返回对象本身用*this
//引用返回 不会返回新的对象 一直返z2 返回的是加完的z2
//值返回 会一直创建一个新的对象 这个案例就是在test2里面 一直返回10
11空指针访问成员函数
//空指针可以访问成员
kong* k = NULL;
k->m();
k->n();
空指针指向一个变量 会报错 解决方法
if (this == NULL)
{
return;
}
12const修饰成员函数
void showP() const 常函数
const changhanshu c;常对象
常对象只能调用常函数
常函数常对象不允许修改普通值,想要修改就要把它变成特殊值
常函数 常对象 限定了只读 但是 mutable 修饰的特殊值可以修改值
mutable int mb;//特殊变量 即使在常函数中 也可以修改这个值 加上关键字 mutable