2.5.2 访问权限
2.5.3 封装
2.5.4 对象特性
2.5.4.1 构造函数
2.5.4.2 析构函数
2.5.4.3 拷贝函数
2.5.4.4 静态成员
2.5.4.5 对象存储空间
2.5.5 友元 friend
2.5.5.1 全局函数做友元
2.5.5.2 类做友元
2.5.5.3 成员函数做友元
2.5.6 运算符重载
2.5.7 继承
2.5.8 多态
C++在执行时,将内存划分为四个区域
代码区:存放函数体二进制代码,由操作系统管理
全局区:存放全局变量和静态变量以及常量
栈区:由编译器自动分配释放,存放函数的参数值、局部变量
堆区:由程序员分配和释放,若程序员不释放则操作系统回收
意义:不同区域存放的数据,赋予不同的生命周期,更大的灵活编程
C++中在程序运行前分为代码区和全局区。
代码区存放CPU执行的机器指令。
代码区是共享的,对于频繁被执行的程序,只需要在内存中有一份代码即可。
代码区是只读的,防止程序意外的修改了他的指令。
全局区中存放全局变量(定义在主函数外的变量)、静态变量(static)、常量(字符串常量、const全局常量)。
全局区在程序结束后由操作系统释放。
由编译器自动分配释放,存放函数的参数值(形参)、局部变量、局部常量(const)等。
注意:不要返回局部变量的地址(栈区数据在函数执行完后自动释放),栈区的数据由编译器开辟和释放。
堆区由程序员分配释放;若程序员不释放,程序结束时由操作系统回收。
int* return_add()
{
//利用new关键字,可以将数据开辟到堆区,new返回的是该数据类型的指针
int* p = new int(10); //初始化为整型数据10
int* arr = new int[10]; //初始化10个元素的数组
for (int i = 0; i < 10; i++)
arr[i] = i;
return p;
}
void main()
{
int* p = return_add();
delete p; //使用delete手动释放内存
delete[] arr; //释放数组要加[]
}
相当于起一个别名
int a = 10;
int &b = a; //a、b指向同一段内存,同时修改
注意:引用必须要初始化,引用一旦初始化后就不可以更改。
形参采用引用传递,会修改实参的值:
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void main()
{
int a = 10;
int b = 20;
sawap(a, b); //执行该函数后a=20,b=10
}
引用的本质是指针常量:
int &ref = a;
//本质上是int* const ref = &a;
int func (int a, int b = 10, int c = 20) //默认参数写在形参
{
return a + b+ c;
}
void main()
{
func(10); //有默认参数可以不传实参
}
注意:1.如果某个形参有了默认参数,后续其它形参也都必须有默认值;2.函数声明有默认参数,函数实现就不能有默认参数。
int add(int a, int)
{
return a+b;
}
void main()
{
add(10, 10);
}
函数重载的满足条件:1、同一作用域;2、函数名相同;3、函数参数类型不同、或个数不同、或顺序不同。
注意:返回值不能作为函数重载的条件;重载函数不要写默认参数,容易出现二义性。
class Student{
//类中的属性和行为,统一称为成员
//属性,又称为成员属性、成员变量
public: //共用权限
string name;
int id;
//行为,又称为成员函数、成员方法
void set_student(string nn, int ii;)
{
name = nn;
id = ii;
}
};
int main()
{
Student ss;
ss.set_student("张三", 1);
}
三种访问权限:
1.公共权限 public 成员 类内可以访问,类外可以访问
2.保护权限 protected 成员 类内可以访问,类外不可以访问,儿子可以访问父亲的保护内容
3.私有权限 private 成员 类内可以访问,类外不可以访问,儿子不可访问父亲的保护内容
class与struct的区别:class默认权限为private,struct默认权限为public。
成员属性私有化的好处:1、可以自己控制读写权限;2、对于写权限,可以检测数据有效性。
类和对象的分文件编写:
1.新建类的h头文件和cpp源文件;
2.在头文件中定义类,并将类中的行为(方法)仅保留声明部分;声明全局变量不赋值,加extern;
3.在源文件中添加对应头文件,补充声明函数的具体内容,并在函数前添加类名::表示其作用域。
构造函数对对象进行初始化,析构函数进行清理,都会自动调用。
1.没有返回值,不用写void
2.函数名与函数相同
3.构造函数可以有参数,可以发生重载
4.创建对象的时候,构造函数会自动调用,而且只调用一次
1.没有返回值,不写void
2.函数名和类名相同,在名称前加~
3.析构函数不可以有参数,不可以重载
4.对象在销毁前,会自动调用析构函数,而且只会调用一次
浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
class Person()
{
Person()
{
cout << "构造函数" << endl;
}
~Person()
{
cout << "析构函数" << endl;
}
Person(const Person &p): //拷贝函数
{
age = p.age;
}
int age;
};
类内声明,类外需要初始化。
1.静态成员变量
所有对象都共享同一块内存;
注意:static 成员变量的内存既不是在声明类时分配,也不是在创建对象时分配,而是在(类外)初始化时分配
可以有public和private不同作用域。
class Person
{
public:
static int age;
};
int Person::age = 20;
2.静态成员函数
有public和private不同作用域。
静态成员函数与普通成员函数的根本区别在于:普通成员函数有 this 指针,可以访问类中的任意成员;而静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数);普通成员函数只能在创建对象后通过对象来调用,因为它需要当前对象的地址。而静态成员函数可以通过类来直接调用,编译器不会为它增加形参 this,它不需要当前对象的地址,所以不管有没有创建对象,都可以调用静态成员函数。
class Person
{
public:
static void func()
{
cout << "static func." << endl;
}
};
//两种方式调用静态成员函数
//1.通过对象
Person p1;
p1.func();
//2.通过类名
Person::func()
只有非静态成员变量会占对象的存储空间,如果对象为空则占一个字节。
友元就是允许一个函数或者类访问另一个类中的私有成员。
class Person
{
Person(int age0) //构造函数 初始化
{
age = age0;
### 最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
### 资料预览
给大家整理的视频资料:

给大家整理的电子书资料:

**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618542503)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
x学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
### 资料预览
给大家整理的视频资料:
[外链图片转存中...(img-av8Z61Mt-1714237598007)]
给大家整理的电子书资料:
[外链图片转存中...(img-vZj9ZI2V-1714237598008)]
**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618542503)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**