c++基础思维导图2
c++基础思维导图2
结构体
结构体的基本概念:用户自定义的数据类型
结构体定义和使用
- struct 结构体名{结构体成员}
- struct 结构体名 变量名;
struct 结构体名 变量名 = {成员1,成员2}
定义式struct 可以不加上分号,但是创建一个结构体数组的时候需要加上分号
定义结构体的关键字是struct,不可以省略;
关键字struct 可以省略;
结构体变量利用操作符" . "访问成员
结构体数组
- struct 结构体名 数组名{元素个数}={{},{}.{}...{}}
结构体和指针
- 操作符->可以通过访问结构体属性
- Student s1;
Student *p=&s1;
结构体嵌套结构体
结构体做函数的参数
- 如果修改主元素的数据就地址传入,不修改就按值传入;
- 函数中的参数改为指针为减少内存空间而不会复制新的版本出来
小作业:通讯录管理系统
程序中的内存模型
针对c++面向对象技术的详细讲解
c++程序在执行的时候大方向分为四个区域
1、代码区
- 存放函数体二进制代码,由操作系统进行管理的
- 代码区是共享的
- 代码区是只读的
2、全局区
- 存放全局变量和静态变量以及常量
- 全局区还包括常量区,字符串常量和其他常量
- 该区域里面的数据结束后由操作系统释放
3.栈区
- 由编译器自动分配释放。存放函数的参数值,局部变量,局部常量等
- 栈区的数据在函数执行之后会自动的释放,所以不要返回局部变量的地址
4.堆区
由程序员分配和释放,若程序员不释放,程序结束时操作系统回收
new
- 例子:
#include
#include
#include
using namespace std;
int *fun_c(){
int * p =new int(10);
return p;
}
int main(){
int * p = fun_c();
cout <<* p<<endl;
//打印的结果是10;
return 0;
}
- new返回的是数据类型的指针
- delete
- 释放内存
- 释放数组的时候使用delete[]
不同区域存放的数据赋予了不同的生命周期,给我们更大的灵活编程
c++中的引用
引用的作用就是给变量起别名
语法:数据类型 &别名=原名
例子
- #include
#include
using namespace std;
int main(){
int a = 10;
int &b =a;
b = 20;
cout << "a =
"<<a<<endl;
cout << "b =
"<<b<<endl;
return 0; //结果是a=b=20;
}
- #include
#include
using namespace std;
int main(){
int a = 10;
int &b =a;
int c = 30;
b = c;
cout << "a =
"<<a<<endl;
cout << "b =
"<<b<<endl;
cout << "c =
"<<b<<endl;
return 0; //结果是a=b=c=30;
}
注意
- 引用必须要初始化
- 引用初始化后不可以改变
引用做函数参数
- 作用:函数传参时,可以利用引用的技术让形参修饰实参
- 优点:可以简化指针修改实参
函数传递
- 地址传递
- 值传递
- 引用传递
引用做函数的返回值
- 不能返回局部变量的引用,可以使用静态变量的引用
引用的本质就是一个指针常量,引用一旦初始化后就不可以发生改变
常量的引用
const int & ref = 10;
- 加上const之后编译器将代码修改:
int temp = 10;
const int & ref = temp;
- 加上const 变为只读状态不可以修改
int & ref =10是不合法的
例子
- #include
using namespace std;
void show(int&);
int main(){
int a =10;
show(a);
cout << a <<endl;//改变了a 的值,输出的结果是1000;
return 0;
}
void show(int &b){
b =1000;
}
- 作用就是传递函数的形参的时候使用const int &就不会改变原来传入的变量的值
函数高级
函数的默认参数
如果调用函数的时候传入了参数的值就优先使用传入的值,没有传入就使用默认参数
如果某个位置已经有了默认参数,那么这个位置往后,从左到右都必须要有默认值
- 错误示范:
#include
using namespace std;
int fun(int,int,int);
int main(){
int t =fun(10,20,30);
cout << t <<endl;
return 0;
}
int fun(int a=10,int b,int c){//这里的a已经有了默认值那么所有的形参都应该设置默认值,否则就会报错
return a+b+c;
}
- 声明有了函数的默认值实现就不能有(声明和实现只能有一个默认参数),为了避免二义性
函数占位参数
就是写函数形参的时候只是写数据的类型
占位参数还可以有默认参数
- 例子:
int fun(int a,int b,int= 20);
int main(){
int t =fun(5,10);
cout << t <<endl;
return 0;
}
int fun(int a,int b,int c){
return a+b+c;
}
函数的重载
函数名可以相同,提高复用性
需要满足的条件
- 同一个作用域下;
- 函数名称相同;
- 函数参数类型不同或者个数不同或者顺序不同;
注意:函数的返回值不可以作为函数重载的条件;
引用作为重载条件,默认参数产生重载的歧义
函数重载的注意事项
类和对象
c++面向对象三大特性:封装、继承、多态
具有属性的事物叫做对象,具有相同性质的对象可以抽象成类
对象特性
构造函数和析构函数
构造函数
构造函数是对象的初始化
构造函数主要作用是创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用
语法
- 类名(){}
- 构造函数没有返回值也不写void
- 函数名称和类相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时候自动调用构造,不需要手动调用
析构函数
析构函数是清理
析构函数主要作用时对象销毁前系统自动调用,执行一些清理工作
语法
- ~类名(){}
- 析构函数没有返回值也不写void
- 函数名称与类名相同,在名称前加上符号~
- 析构函数不可以由参数,因此不可以发生重载
- 程序在对象摧毁前会自动析构,无需手动调用只会调用一次
作用:析构函数可以将堆区开辟数据做释放操作
构造函数的分类及调用
- 按照参数分类:有参构造和无参构造;
- 按照类型分类:普通构造和拷贝构造
- 拷贝调用函数使用的时机
- 使用一个已经创建完毕的对象来初始化一个新对象
- 值传递的方式给函数参数传递
-
以值的方式返回局部对象
- 三种调用方式:括号法、显示法、隐式转换法
- 注意:1.匿名对象
特点:当前执行结束后,系统会理机回收掉匿名函数;
2.不要利用拷贝构造函数,初始化匿名对象
3.隐式转换法
- 构造函数和析构函数是编译器自动调用,完成对象初始化和清理工作
-
如果不提供析构和构造函数,编译器会提供,提供的都是空实现
初始化列表
example
Person():m_A(10),m_B(20),m_C(30){}
- Person(int a,int b,int
c):m_A(a),m_B(b),m_C(c){}
深拷贝和浅拷贝
浅拷贝:简单的赋值拷贝操作;
- 浅拷贝带来的问题就是堆区的内存重复释放
深拷贝:在堆区重新申请空间,进行拷贝操作
- 如果属性有在堆区开辟的,一定要自己提供拷贝函数,防止浅拷贝带来的问题
类对象作为类成员
- 当其他类的对象作为本类成员,构造时候先构造类对象
静态成员
静态成员就是成员表变量和函数前面加上关键字static,称为静态成员
静态成员变量
- 所有对象共享一份数据
- 在编译阶段分配内存
- 类内声明,类外初始化
静态成员函数
- 所有对象共享同一函数
- 静态成员函数只能访问静态成员变量
成员变量和成员函数分开存储
- 在c++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上
- 空对象占内存空间是1;
c++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
- 空对象占字节数是1,为了表示对象的内存位置;对象中有静态成员变量,所占字节数还是1,说明了静态成员变量不属于类对象上,同理成员函数不属于类对象上
this指针
- this指针指向被调用的成员函数所属的对象
- this指针式隐含每一个非静态成员函数的一种指针
- this指针的用途:
1.当形参和成语那变量同名时,可以用this指针来区分;
2.在类的非静态成员函数中返回对象本身可使用return *this
空指针访问成员函数
- c++中空指针也是可以调用成员函数的,但是也要注意没有用到的this指针;如果用到this指针,需要加以判断保证代码的健壮性
const修饰成员函数
常函数
- 成员函数后加const后我们称为这个函数为常函数
- 常函数内不可以修改成员属性
- 成员属性声明时关键mutable,在常函数中依然可以修改
常对象
- 声明对象前加const称该对象为常对象
- 常对象只能调用常函数
友元
友元的关键字为friend
友元的目的就是为了一个函数或者类访问另一个类中私有成员
友元的三种实现
- 全局函数做友元
- 类做友元
- 成员函数做友元
运算符重载
- 运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
- 对于内置的数据类型的表达式的运算符是不可能改变的;
不要滥用重载;
(加减乘除)运算符重载
例子
- #include
using namespace std;
class Person{
public:
int m_a;
int m_b;
/* Person operator+(Person
&p){
Person temp;
temp.m_a =
this->m_a+p.m_a;
temp.m_b =
this->m_b+p.m_b;
return temp; //使用成员函数运算符重载
}*/
};
//使用全局函数运算符重载
Person operator+(Person &p1,Person &p2){
Person temp;
temp.m_a = p1.m_a+p2.m_a;
temp.m_b = p1.m_b+p2.m_b;
return temp;
}
void test01(){
Person p1;
p1.m_a = 10;
p1.m_b = 10;
Person p2;
p2.m_a = 20;
p2.m_b = 20;
Person p3 = p1+p2;
cout
<<p3.m_a<<endl;
cout <<
p3.m_b<<endl;
}
int main(){
test01();
return 0;
}
左移运算符重载
- 作用:可以输出自定义数据类型
递增运算符重载
- 作用:通过重载递增运算符,实现自己的整形数据
- 注意:前自增运算符重载时返回的时引用,后自增运算符重载时返回的时值,自减同理
赋值运算符重载
关系运算符重载
函数调用运算符重载
继承
继承的作用
- 作用:定义类时,下级别的成员除了拥有上一级的共性,还有自己的特性,这时候可以考虑继承的技术,减少重复代码
- 派生类时从基类中继承过来的,一类是自己增加的成员,从基类继承过来的表现其共性,而新增的成员体现了其个性
继承语法
class 子类:继承方式 父类
class A:public B;
A类为子类或派生类
B类为父类或基类
继承的方式有三种
- 公共继承;
- 保护继承;
- 私有继承;
继承中同名处理方式
继承中同名的静态成员在子类对象上如何进行访问
- 访问子类同名成员--直接访问即可
- 访问父类同名成员,需要加作用域
继承中同名静态成员函数如何进行访问
- 和同名静态成员相同
继承的访问方式
- 通过对象进行访问
- 通过类名进行访问
子类中如果出现和父类相同的成员就会把父类中的成员全部隐藏,解决方法就是加上作用域
多继承语法
- 语法:class 子类:
继承方式 父类1, 继承方式 父类2 ... - 多类继承可能会引发父类中有同名成员出现,需要加作用域区分
- 在实际开发中不建议多用多继承
- 语法:class 子类:
菱形继承概念
两个派生类继承同一个基类
又有某个类同时继承连个派生类
这种继承被称为菱形继承或者钻石继承
菱形继承容易出现多继承二义性的情况,也容易浪费内存
利用虚继承,解决菱形继承问题,继承之前,加上关键字 virtual 变为虚继承,其中最开始的基类称为虚基类
- 其内部本质上是一个指针,用一个虚指针指向同一个数据
- 语法 class
类名: virtual public 要继承类名;
封装
意义:
1.将属性和行为作为一个整体,表现生活中的事物;
2.将属性和行为加以权限控制
权限控制
三种访问权限:
公共权限(public):成员类内可以访问,类外可以访问
保护权限(protected):成员类内可以访问,类外不能访问
- 子类可以访问父类保护的内容
私有权限(private):成员类内可以访问,类外不能访问
- 子类不可以访问父类私有的内容
c++中struct和class的区别
- 唯一的区别是默认的访问权限不同
- struct默认访问权限是公有
- class默认访问权限是私有
成员属性设置为私有的优点
将所有成员属性设置为私有,可以自己控制读写权限
对于写权限,我们可以检测数据的有效性
例子
- #include
#include
using namespace std;
class student{
public:
void set_name(string name){
m_name = name;
}
string get_name(){
return m_name;
}
int get_age(){
return age;
}
void set_classes(string
class1){
classes=class1;
}
private:
string m_name;//可读可写
int age=18;//可读
string classes;//可写不可读
};
int main(){
student st1;
st1.set_name("jerry");
st1.set_classes("english
education");
cout <<"学生的名字是:
"<<st1.get_name()<<endl;
cout <<"学生的年龄是:
"<<st1.get_age()<<endl;
return 0;
}
多态
多态分为两类
静态多态
- 函数重载和运算符重载属于静态多态,复用函数名
动态多态
- 派生类和虚函数实现运行时多态
静态多态和动态多态的区别
- 静态多态的函数地址早绑定-编译阶段就确定函数地址
- 动态多态的函数地址晚绑定-运行阶段确定函数地址
多态优点
- 代码组织结构清晰
- 可读性强
- 利于前期和后期的扩展以及维护
- 组织结构清晰
在实际的开发中是开闭原则,对扩展进行开发,对修改进行关闭;
c++的开发中提倡利用多态设计组织架构,因为多态的优点有很多
纯虚函数和多态类
在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写内容,因此可以将虚函数改为纯虚函数
纯虚函数的语法:virtual 返回类型 函数名 (参数列表) = 0;
当类中出现了纯虚函数,这个类也称为抽象类
抽象类的特点
- 无法实例化对象
- 子类必须重写抽象类中的纯虚函数,否则也属于抽象类
虚析构和纯虚析构
- 多态使用时,如果子类中属性开辟堆区,那么父类指针在释放时无法调用到子类的析构代码。
解决方法:将父类中的析构函数改为虚析构或者纯虚析构
- 虚析构和纯虚析构共性:
1.可以解决父类指针释放子类对象;
2.都需要具有具体的函数实现;
虚构和纯虚析构区别:
1.如果纯虚析构,该类属于抽象类,无法实现实例对象
虚构语法:virtual ~类名(){}
纯虚构语法:virtual ~类名() =
0;总结
- 1.虚析构或者纯虚析构就是用来解决通过父类指针释放子类对象;
- 2.如果子类中没有堆区数据,可以不写为虚析构或者纯虚析构;
- 3.拥有纯虚析构函数的类也属于抽象类;
c++基础思维导图2的更多相关文章
- java 基础-思维导图
思维导图的好处 最近看了一些文章的思维导图,发现思维导图真是个强大的工具.了解了思维导图的作用之后,觉得把它运用到java上应该是个不错的想法,这样回顾知识点的时候一目了然,快速知道自己的短板. 思维 ...
- java基础思维导图,让java不再难懂
java基础思维导图,让java不再难懂 原文链接 https://my.oschina.net/u/3080373/blog/873056 最近看了一些文章的思维导图,发现思维导图真是个强大的工具 ...
- python开发基础--思维导图
开始学习python,相当于零基础 非自学,自学的痛苦不想体会和尝试,毕竟不会很友好,知乎上看到很多说自学的好处啊噼里啪啦的.嗯,说的很对,但是我偏不听,略略略.锻炼我的自学能力,这还需要锻炼吗,百度 ...
- javascript基础 思维导图2
来源于:http://www.cnblogs.com/xianyulaodi/p/5886128.html 1.javascript数据类型 2.javascript数组 3.javascript运算 ...
- java基础思维导图
如果图片看不清楚的可以把图片另存为桌面放大看哈
- Hadoop基础思维导图
- Unity3d 脚本基础 思维导图
盘点下Unity的脚本知识.
- java语法基础思维导图
- c#基础思维导图
随机推荐
- 1.设计模式第一步-《设计模式从头到脚舔一遍-使用C#实现》
更新记录: 完成第一次编辑:2022年4月23日20:29:33. 加入小黄人歌曲:2022年4月23日21:45:36. 1.1 设计模式(Design Pattern)是什么 设计模式是理论.是前 ...
- hyperlpr centos 使用记录
1.下载最新版python3.7 Anacondawget https://repo.anaconda.com/archive/Anaconda3-5.3.1-Linux-x86_64.sh 2.安装 ...
- kali 漏洞扫描
前言 漏洞扫描器是一种能够自动在计算机.信息系统.网络及应用软件中寻找和发现安全弱点的程序.它通过网络对目录系统进行探测,向目标系统发送数据,并将反馈数据与自带的漏洞特征库进行匹配,进而列举目标系统上 ...
- RPA供应链管制单修改机器人
背景:供应链环节中,研发物料时而因为市场缺货等原因无法采购,资材部需登入系统修改物料管制单. 操作流程:登录PDM系统中读取数据.登录ERP系统中更新数据. 人工操作:每日耗时3.5小时,出现一定比例 ...
- Java开发学习(九)----IOC之核心容器
这里所说的核心容器,大家可以把它简单的理解为ApplicationContext,前面虽然已经用到过,但是并没有系统的介绍过,接下来咱们从以下几个问题入手来下容器的相关知识: 如何创建容器? 创建好容 ...
- 模电Multisim仿真Rb变化对Q点和电压放大倍数的影响
一.目的 研究Rb变化对Q点和Au的影响. 二.方法描述 仿真电路如下所示.晶体管采用FMMT5179其参数BF=133,RB=5Ω. (1)分別测量Rb=3MΩ和3.2MΩ时得UCEQ和Au.由于信 ...
- git的工作原理和git项目创建及克隆
Git基本理论(重要)三个区域Git本地有三个工作区域:工作目录(Working Directory).暂存区(Stage/Index).资源库(Repository或Git Directory).如 ...
- ICMP 介绍
简介 ICMP(Internet 控制报文协议,Internet Control Message Protocol , RFC 792).主要用于在IP主机与路由器之间传递控制消息,用于报告主机是否可 ...
- Scala(二)IO流 读取文件和保存文件
package com.shujia.scala import java.io.{BufferedReader, FileReader, FileWriter} import scala.io.{Bu ...
- Android开启OTG功能/USB Host API功能
Android USB 模式简介 设备模式 当计算机或其他USB主机需要连接安卓设备时,此时安卓设备是作为"USB设备"角色的,在计算机上显示为 USB 外设.现在的安卓设备已经被 ...