本阶段主要是对自身C++的查漏补缺,巩固知识
目录
一、指针的复习
1.const修饰指针
(1)常量指针
语法:
const int *p=&a
特点:指针的指向可以修改,而指针指向的值不能改
(2)指针常量
语法:
int *const p=&a
特点:指针的指向不可以修改,而指针指向的值可以修改
(3)const既修饰指针,又修饰常量
const int *const p=&a
特点:指针的指向和指针指向的值都不可以修改
2.利用指针遍历数组
示例:
#include<iostream>
using namespace std;
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr;
for (int i = 0; i < 10; i++)
{
cout << "第" << i + 1 << "个元素是" << *p<<endl;
p++;
}
system("pause");
return 0;
}
3.指针传参--地址传递
地址传递可以修饰实参,而值传递不可以
示例:
#include<iostream>
using namespace std;
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
void swap2(int *p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p1 = temp;
}
int main()
{
int a = 10;
int b = 20;
swap1(a, b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
swap2(&a, &b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
system("pause");
return 0;
}
4.结构体指针
作用:通过指针访问结构体的成员
利用"->"操作符可以通过结构体指针访问结构体属性
示例:
#include<iostream>
#include<string>
using namespace std;
struct student
{
string name;
int score;
int age;
};
int main()
{
//创建一个结构体变量
student s = { "张三",89,19 };
//创建一个结构体指针
student* p = &s;
//通过指针访问结构体成员
cout << p->age;
system("pause");
return 0;
}
结果:
二、内存分区模型
1.内存四区
代码区:存放函数体的二进制代码,由操作系统进行管理的
全局区:存放全局变量,静态变量以及常量
栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
内存四区意义:不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程
2.代码区
3.全局区
该区域的数据在执行程序后由操作系统释放,存放全局变量,静态变量以及常量(不包括const 修饰的局部常量)
4.栈区
该区域的数据由编译器自动分配释放,存放函数的参数值,局部变量
PS:不要返回局部变量的地址
5.堆区
由程序员分配和释放
在C++中主要利用new来开辟内存
利用new关键字,可以把数据开辟到堆区,若不释放,则数据一直存在
6.new运算符
new可以在堆区创建数据,返回的是该数据类型的指针
示例:
#include<iostream>
using namespace std;
int* func()
{
int* p = new int(10);//在堆区创建整型数据,new的返回值为指针
return p;
}
int main()
{
int* p = func();
cout << *p << endl;
}
释放堆区数据:delete
当我们不使用delete释放堆区内存时,堆区数据可以持续使用。当我们释放之后,将不能正常使用。
new定义数组语法:int *arr=new int[]
delete释放数组:delete[]arr
三、引用
1.引用的定义:
引用就是给变量取别名
语法:数据类型 &别名=原名
2.引用做函数参数
可以用引用的技术让形参修饰实参
示例:
#include<iostream>
using namespace std;
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 20;
int b = 40;
swap(a, b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
system("pause");
return 0;
}
结果:
3.引用的本质
引用的本质实际上是一个指针常量(即相当于int *const p(整型形式))
即指针的指向不能改变,而指针指向的值可以改变
四、函数的重载
1.条件
条件:
(1)在同一个作用域下
(2)同一个函数名
(3)函数参数类型不同,或者个数不同,或者顺序不同
(4)函数的返回值不能作为函数重载的条件
五、类的封装
1.成员属性私有化
改变私有化的成员属性可以通过在public部分自定义相关函数访问private,从而来改变私有化的成员属性,若不允许被改变,则不在public自定义相关函数
例如:
#include<iostream>
#include<string>
using namespace std;
class student
{
public:
void setname(string name)
{
m_name = name;
}
string getname()
{
return m_name;
}
private:
//姓名
string m_name;
//年龄
int m_age=0;
//银行卡密码
int m_arr[6] = {};
};
int main()
{
student stu1;
stu1.setname("张三");
string name=stu1.getname();
cout << name<<endl;
system("pause");
return 0;
}
结果:
六、对象特性
1.构造函数与析构函数
构造函数语法:类名(){}
1.构造函数,没有返回值也不写void
2.函数名称与类名相同
3.构造函数可以有参数,因此可以发生重载
4.程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
析构函数语法:~类名(){}
1.析构函数,没有返回值也不写void
2.函数名称与类名相同,在名称前加入符号~
3.析构函数不可以有参数,因此不可以发生重载
4.程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
PS:析构函数要在对象即将销毁前才会调用
2.构造函数的分类及调用
两种分类方式:
按参数分为:有参构造和无参构造
按类型分为:普通构造和拷贝构造
拷贝构造:
语法:类名(const 类名&对象名){}
三种调用方式:
括号法: 类名 对象名(参数)
例如:class Person:.......
调用时:无参数时:Person p1()
有参数时:Person p2(a)
拷贝构造时:Person p3(p2)
显示法:类名 对象名=类名(参数)
例如:class Person:.......
调用时:无参数时:Person p1
有参数时:Person p2=Person(a)
拷贝构造时:Person p3=Person(p2)
隐式转换法
例如:class Person:.......
调用时:无参数时:Person p1
有参数时:Person p2=a
拷贝构造时:Person p3=p2