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 ...
    • 多类继承可能会引发父类中有同名成员出现,需要加作用域区分
    • 在实际开发中不建议多用多继承
  • 菱形继承概念

    • 两个派生类继承同一个基类

    • 又有某个类同时继承连个派生类

    • 这种继承被称为菱形继承或者钻石继承

    • 菱形继承容易出现多继承二义性的情况,也容易浪费内存

    • 利用虚继承,解决菱形继承问题,继承之前,加上关键字 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的更多相关文章

  1. java 基础-思维导图

    思维导图的好处 最近看了一些文章的思维导图,发现思维导图真是个强大的工具.了解了思维导图的作用之后,觉得把它运用到java上应该是个不错的想法,这样回顾知识点的时候一目了然,快速知道自己的短板. 思维 ...

  2. java基础思维导图,让java不再难懂

    java基础思维导图,让java不再难懂 原文链接  https://my.oschina.net/u/3080373/blog/873056 最近看了一些文章的思维导图,发现思维导图真是个强大的工具 ...

  3. python开发基础--思维导图

    开始学习python,相当于零基础 非自学,自学的痛苦不想体会和尝试,毕竟不会很友好,知乎上看到很多说自学的好处啊噼里啪啦的.嗯,说的很对,但是我偏不听,略略略.锻炼我的自学能力,这还需要锻炼吗,百度 ...

  4. javascript基础 思维导图2

    来源于:http://www.cnblogs.com/xianyulaodi/p/5886128.html 1.javascript数据类型 2.javascript数组 3.javascript运算 ...

  5. java基础思维导图

    如果图片看不清楚的可以把图片另存为桌面放大看哈

  6. Hadoop基础思维导图

  7. Unity3d 脚本基础 思维导图

    盘点下Unity的脚本知识.

  8. java语法基础思维导图

  9. c#基础思维导图

随机推荐

  1. 1.设计模式第一步-《设计模式从头到脚舔一遍-使用C#实现》

    更新记录: 完成第一次编辑:2022年4月23日20:29:33. 加入小黄人歌曲:2022年4月23日21:45:36. 1.1 设计模式(Design Pattern)是什么 设计模式是理论.是前 ...

  2. hyperlpr centos 使用记录

    1.下载最新版python3.7 Anacondawget https://repo.anaconda.com/archive/Anaconda3-5.3.1-Linux-x86_64.sh 2.安装 ...

  3. kali 漏洞扫描

    前言 漏洞扫描器是一种能够自动在计算机.信息系统.网络及应用软件中寻找和发现安全弱点的程序.它通过网络对目录系统进行探测,向目标系统发送数据,并将反馈数据与自带的漏洞特征库进行匹配,进而列举目标系统上 ...

  4. RPA供应链管制单修改机器人

    背景:供应链环节中,研发物料时而因为市场缺货等原因无法采购,资材部需登入系统修改物料管制单. 操作流程:登录PDM系统中读取数据.登录ERP系统中更新数据. 人工操作:每日耗时3.5小时,出现一定比例 ...

  5. Java开发学习(九)----IOC之核心容器

    这里所说的核心容器,大家可以把它简单的理解为ApplicationContext,前面虽然已经用到过,但是并没有系统的介绍过,接下来咱们从以下几个问题入手来下容器的相关知识: 如何创建容器? 创建好容 ...

  6. 模电Multisim仿真Rb变化对Q点和电压放大倍数的影响

    一.目的 研究Rb变化对Q点和Au的影响. 二.方法描述 仿真电路如下所示.晶体管采用FMMT5179其参数BF=133,RB=5Ω. (1)分別测量Rb=3MΩ和3.2MΩ时得UCEQ和Au.由于信 ...

  7. git的工作原理和git项目创建及克隆

    Git基本理论(重要)三个区域Git本地有三个工作区域:工作目录(Working Directory).暂存区(Stage/Index).资源库(Repository或Git Directory).如 ...

  8. ICMP 介绍

    简介 ICMP(Internet 控制报文协议,Internet Control Message Protocol , RFC 792).主要用于在IP主机与路由器之间传递控制消息,用于报告主机是否可 ...

  9. Scala(二)IO流 读取文件和保存文件

    package com.shujia.scala import java.io.{BufferedReader, FileReader, FileWriter} import scala.io.{Bu ...

  10. Android开启OTG功能/USB Host API功能

    Android USB 模式简介 设备模式 当计算机或其他USB主机需要连接安卓设备时,此时安卓设备是作为"USB设备"角色的,在计算机上显示为 USB 外设.现在的安卓设备已经被 ...