引用
概念
引用是个别名
格式
数据类型 &引用名 = 同类型的变量名 (&引用符号)
数据类型 &引用名 = 同类型的变量名 (&引用符号)int a = 10;int &b = a; //给a取个别名叫b, b引用a
数组引用
int a;a=10;int &b = a;cout << a << " " << b << endl;b=20;cout << a << " " << b << endl;int arr[5] = {10,20,30,40,50};int (*p)[5] = &arr;int (&str)[5] = arr;cout << arr[3] << " " << str[3] << endl;cout << (*p)[3] << endl;cout << &arr << endl;
函数引用
int max(int a,int b)
{return a>b?a:b;
}
int main()
{int (*p)(int,int) = max;int (&fun)(int,int) = max;cout << p(13,32) << endl;cout << fun(12,53) << endl;return 0;
}
当结构体中有引用成员时
当结构体中有引用成员,使用该结构体类型,定义结构体变量时,就必须定义的同时初始化,就不可以先定义,后赋值。
struct student
{string name;int age;double &score;
};int main()
{double a;cout << "请输入" << endl;cin >> a;struct student stu = {"zhang",10,a};stu.name = "zhang";cout << stu.name << " " << stu.age << " " << stu.score << endl;return 0;
}
值传递,地址传递,引用传递
值传递:一定不改变原值
地址传递:可能改变原值
引用传递:可能改变原值
space std;void fun(int a, int b)// int a = a
{a++;b++;
}void fun2(int *a, int *b) //int *a = &a
{*a++;*b++;
}void fun3(int &a, int &b)//int &a = a, int &b = b
{int c = a;b++;
}int main()
{int a = 10, b = 20;fun(a,b); //传值,一定不会改变目标的值cout << "main: a = " << a << " b = " << b << endl;fun2(&a, &b); //传址,可能会改变目标的值,具体看代码设计cout << "main: a = " << a << " b = " << b << endl;fun3(a,b);//传引用,可能会改变目标的值,具体看代码设计cout << "main: a = " << a << " b = " << b << endl;return 0;
}
当引用作为函数的返回值的时候
要求返回的变量生命周期足够的长(static修饰或者malloc申请空间)
指针和引用的区别
指针和引用都可以修改变量的值,但本质不同:指针是通过地址改变目标的值,而引用就是目标本身
指针:
- 存储地址的变量
- 可以先定义,后指向
- 可以改变指向
- 定义指针需要重新申请空间
- 有指针数组
- 有多级指针
引用:
- 引用是个别名
- 必须定义的同时初始化
- 指针可以改变指向,而引用一旦指定目标,就不能被改变
- 定义引用不用重新申请空间
- 没有引用数组(引用不是数据类型)
- 没有二级引用
const
const修饰的为只读变量,也成为常变量
const修饰的局部变量在栈区,const修饰的全局变量在静态区的.ro段
const修饰的变量必须在定义的同时初始化
如果想要引用常变量,需要常引用(const int &b = a)
函数重载
概念
在同一个作用域下,两个以上的函数,取相同的函数名,其函数的形参类型或者形参个数不同,编译器会根据实参的参数类型或者个数自动调用匹配的函数,这就是函数重载。
注:返回值类型不同不算重载
例如以下三个函数为重载
int task(int x)
{}int task(char x)
{}
int task(int x,int b)
{}
使用函数重载实现不同数据类型之和
#include <iostream>using namespace std;int add(int x, int y)
{return x+y;
}double add(double x, double y)
{return x+y;
}int add(char x, char y)
{return x+y;
}string add(string x, string y)
{return x+y;
}int main()
{cout << add(1,2) << endl;cout << add(1.24, 4.56) << endl;cout << add('a', '1') << endl;cout << add("hello", "world") << endl;return 0;
}
带有默认参数的函数定义和使用
#include <iostream>using namespace std;void fun(string name = "kity")
{cout << name << endl;
}
int main()
{fun();fun("hello");return 0;
}
哑元(了解)
函数在定义形参时,只定义形参类型,不定义形参名,在函数中也不使用。
作用:没有作用,占位。
内联函数
在函数前面加上inline关键字,那么该函数就是内联函数
要求:
- 函数的体积要小(代码一般不超过5行)
- 函数不能有复杂语句(循环,递归)
作用:提高代码的运行效率
原因:内联函数在编译时展开
内敛函数和带参宏的区别
内联函数:
- 编译时展开
- 内联函数时函数调用
带参宏:
- 预处理时打开
- 带参宏是替换
C++中的结构体
C++中结构体和C语言中结构体的区别
C语言中的结构体在C++中依然适用
C++:
- 可以在定义结构体的时候赋初始值
- 结构体中可以有函数
- 在使用结构体类型定义变量时可以省略关键字struct
- 结构体的成员有访问权限
- 结构体有继承
- 结构体有特殊的成员函数
C语言:
- 定义结构体时不能赋初始值
- 结构体中不能有函数
- 在使用结构体类型定义变量时不可以省略关键字struct
- 结构体成员没有访问权限
- 结构体不能继承
- 及沟通中没有特殊的成员函数
*C++中结构体名一般首字母大写
类
概念
C++中的类由C++中的结构体演变而来,只是默认的访问权限和默认的继承方式,以及关键字不同,其他都相同。
一般构造数据类型中既有变量又有函数的类型,由类来完成。
C++中结构体和类的区别
默认访问权限:
C++中结构体的默认访问权限是:public共有的
C++中类的默认访问权限是:private共有的
默认继承方式:
C++中结构体的默认继承方式是:public共有的
C++中类的默认继承方式是:private共有的
关键字:
C++结构体:struct
C++类:class
访问权限:public共有的,private共有的,protected保护的
格式
class 类名
{public:公共的数据成员、成员函数protected:受保护的数据成员,成员函数private:私有的数据成员,成员函数
};
访问权限的介绍
public:共有权限,表示该权限下的成员,表示该权限的属性(变量),方法(函数)在类内,子类,类外都能访问。
protected:该权限是受保护权限,表示该权限下的属性(变量)、方法(函数),在类内、子类可以被访问,而类外不能被访问。
private:该权限是私有权限,该权限下的属性(变量)、方法(函数),只能在类内被访问,子类、类外不可以被访问。
封装
类的三大属性:封装、继承、多态
封装:写一个类的过程,就是将数据和对数据的处理捆绑在一起的过程。
属性 + 方法
变量 + 函数
相关名称: 类内都可以成为成员,而成员可以具体分为 数据成员、成员函数。
#include <iostream>using namespace std;//封装一个 学生 类
class Stu
{int a; //默认私有访问权限
private:string name;
protected:int age;
public:double score;public:dan
当成员函数的形参名和数据成员同名时
表明该数据成员属于哪个类,即加上类名和作用域限定符。
类里的每个非静态成员函数,都隐藏了一个this指针形参。
this指针
类里的每个非静态成员函数,都隐藏了一个this指针形参。
谁使用我,我就指向谁。
this指针的原型:
eg : Stu * const this; //指向不可变,指向里的值可变
类外定义成员函数
在类内声明函数
在类外定义成员函数,需要表明该函数属于哪个类的,即加上类名和作用域限定符
#include <iostream>using namespace std;//封装一个 学生 类
class Stu
{int a; //默认私有访问权限
private:string name;
protected:int age;
public:double score;public:;void init(string n, int a, double s);void show();
};//在类外定义成员函数
void Stu::init(string name, int age, double score) // Stu * const this
{this->name = name;this->age = age;this->score = score;//this = nullptr; // NULL this指针使用过程中 指向不可变
}void Stu::show()
{cout << this << endl;cout << name << endl; //类内可以访问私有成员cout << age << endl; //类内可以访问受保护成员cout << score << endl; //类内可以访问共有成员
}int main()
{//使用学生这样的类 实例化一个学生对象Stu s1;//s1.name = "张三"; //类外不可以访问私有成员//s1.age = 20; //类外不可以访问受保护成员s1.score = 99; //类外可以访问公共的成员s1.init("张三", 32, 78);s1.show();return 0;
}
练习
自己封装一个矩形类(Rect),拥有私有属性:宽度(width)、高度(height),
定义公有成员函数:
初始化函数:void init(int w, int h)
更改宽度的函数:set_w(int w)
更改高度的函数:set_h(int h)
输出该矩形的周长和面积函数:void show()
#include <iostream>using namespace std;//封装一个矩形类
class Rect
{
private:int width;int height;
public:;void init(int w,int h);void set_w(int w);void set_h(int h);void show();
};//在类外定义成员函数
void Rect::init(int w,int h)
{this->width = w;this->height = h;
}void Rect::set_w(int w)
{this->width = w;
}void Rect::set_h(int h)
{this->height = h;
}void Rect::show()
{cout << "面积:" << width*height << endl;cout << "周长:" << 2*width+2*height << endl;
}int main()
{Rect s1;s1.init(4,5);s1.show();return 0;
}