c++学习之面向对象篇章

类和对象
    c++面向的对象的三大特性为:封装、继承、多态
    c++认为万事万物都皆为对象,对象上有其属性和行为
    具有相同性质的对象,我们可以抽象称为类,人属于人类,车属于车类
    
    
    封装
        封装的意义:
            将属性和行为作为一个整体,表现生活中的实物
            将属性和行为加以权限控制
        封装意义一:
            在设计类的时候,属性和行为写在一起,表现事物
            语法:class 类名 {访问权限 属性/行为}

                //类中的属性和行为  统一称为成员
                //属性 成员属性 成员变量
                //行为 成员函数 成员方法
                
        封装意义二:
            类在设计是,可以把属性和行为放在不同的权限下,加以控制
            访问权限有三种
            1、public     公共权限    类内可以访问 类外可以访问
            2、protected 保护权限    类内可以访问 类外不可以访问 儿子也可以访问父亲中的保护内容
            3、private     私有权限    类内可以访问 类外不可以访问 儿子不可以访问父亲的私有内容
            
        struct和class的区别
            struct默认权限是公共public
            class默认权限是私有private
            
        //将成员属性设为私有
            //1、可以自己控制读写权限
            //2、对于写可以检测数据的有效性

        
    构造函数和析构函数
        
        构造函数 进行初始化操作
            1、没有函数值 不用谢void
            2、函数名 与类名想用
            3、构造函数可以有参数,可以发生重载
            4、创建对象的时候,构造函数会自动调用,而且只调用一次
            
        析构函数  进行清理的操作
            1、没有返回值 不写void
            2、函数名和类名相同  在名称前加~
            3、析构函数不可以有参数的,不可以发生重载
            4、对象在销毁前,会自动调用析构函数,而且只会调用一次
            
        构造函数的分类
            按照参数分类   无参构造(默认构造)和有参构造
            按照类型分类  普通构造  拷贝构造
                注意事项:
                    person p1;调用默认构造函数的时候,不要加()
                        //因为下面这行代码,编译器会认为是一个函数的声明,不会认识在创建对象
                        //person p1();
                    不要利用拷贝构造函数 初始化匿名对象  编译器会认为person(p3) === person p3;
            使用方法
                括号法
                    person p2(100);
                    person p3(p2);
                显示法
                    person p2 = person(10);
                隐式转换法
                    person p4 = 10;//相当于写了person p4 = person(10);


        构造函数调用规则
            默认情况下,c++编译器至少给一个类添加三个函数
                1、默认构造函数(无参,函数体为空)
                2、默认析构函数(无参,函数体为空)
                3、默认拷贝构造函数,对属性进行值拷贝
            
            构造函数调用规则如下
                如果用户定义有参构造函数 c++不再提供默认无参构造   但是会提供默认拷贝构造
                如果用户定义拷贝构造函数 c++不会再提供其他构造函数
                
            //初始化列表初始化属性
            person13(int a,int b, int c) :m_a(a), m_b(b), m_c(c) {}
            person13 p(3,2,1);
            
            //当其它类的对象作为本类成员,构造时先构造类对象,再构造自身,析构的顺序与构造相反
            
        //静态成员函数
        //所有对象共享同一个函数
        //静态成员函数只能访问静态成员变量
        //静态函数中  非静态变量  不可以访问  无法区分到底是哪个对象的m_b
        //类外访问不到私有静态成员函数
            
        //成员变量和成员函数 分开存储
            非静态成员变量  属于类的对象上的
            静态成员变量  不属于类对象上
            非静态成员函数  不属于类对象上
            静态成员函数 不属于类对象上
            
            //空对象占用的内存空间为:1
            //c++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
            //每个空对象也应该有一个独一无二的内存地址
            
        
        this指针概念
            this指针指向被调用的成员函数所属的对象
            this指针是隐含没一个非静态成员函数内的一种指针
            this指针不需要定义,直接使用即可
        
        this指针的用途
            当形参和成员变量同名时,可用this指针来区分                   //解决名称冲突
            在类的非静态成员函数中返回对象本身,可使用return *this        //返回对象本身用*this
            
    
        const修饰成员函数
            常函数:
                成员函数加const后我们成为这个函数为常函数
                常函数内不可以修改成员属性
                成员属性声明时加关键字mutable后,在常函数中依然可以修改
            常对象
                声明对象前加const成该对象为常对象
                常对象只能调用常函数
                
        友元
            友元的目的就是让一个函数或者类 访问另一个类中的私有成员
            
            全局函数做友元
            类做友元
            成员函数做友元

        
    运算符重载
        概念:对已有的运算符重新进行定义,赋予另一种功能,以适应不同的数据类型
        
        //函数调用运算()也可以重载
        //由于重载后使用的方式非常想函数额调用,因为称为仿函数
        //仿函数没有固定写法,非常灵活

    
    继承
        继承是面向对象三大特性之一
        
        继承的好处:
            减少重复代码
            语法:class子类:继承方式 父类
            子类 也成为 派生类
            父类 也成为 基类
        
        继承方式:
            公共继承
            保护继承
            私有继承
                //父类中所有非静态成员属性都会被子类继承下去
                //父类中私有成员属性 是被编译器给隐藏了  因此是访问不到 但是确实是被继承下去了
    
    
        vs2017开发人员命令工具
            利用开发人员命令提示工具查看对象模型
            转盘盘符 D:
            跳转文件路径 cd 具体路径
            查看命名
             cl /d1 reportSingleClassLatout类名 文件名
                
    
    
            继承中的构造和析构顺序如下
                //先构造父类再构造子类 析构的顺序和构造的顺序相反
            
            //继承同名成员处理方式
                如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数
                //1、子类对象可以直接访问到子类中同名成员
                //2、子类对象家作用域可以访问到父类同名成员
                //3、当子类与父类拥有同名的成员函数 子类会隐藏父类中同名成员函数 如作用域可以访问到父类中同名函数
        
            菱形继承
                概念:
                    两个派生类继承同一个基类
                    又有某个类同时继承着两个派生类
                    这种继承被称为菱形继承,或者钻石继承
                
                菱形继承带来的主要问题是自类继承两份相同的数据,导致资源浪费以及毫无意义,利用虚继承可以解决菱形继承问题
                继承之前 加上关键字 virtual变为虚继承    
                
    
    多态
    多态分两类
        静态多态:函数重载和运算符重载属于静态多态,复用函数名
        动态多态:派生类和虚函数实现运行时多态
        
    静态多态和动态多态的区别:
        静态多态的函数地址早绑定-编译阶段确定函数地址
        动态多态的函数地址晚绑定-运行阶段确定函数地址
        
    
    虚函数    virtual
    如果想执行让猫说话,那么这个函数地址就不能提前绑定,需要在运行阶段进行绑定,也就是地址晚绑定
    
    动态多态满足条件
    1、有继承关系
    2、子类需要重写父类的虚函数
    动态多态的使用
    1、父类的执行或者引用 执行子类对象
    
    
    vfptr -虚函数(表)指针
    v    - virtual
    f    - function
    ptr    - pointer
    
    vftable    -    虚函数表
    v    - virtual
    f    - function
    table - table
    
    当自雷重写父类的虚函数
    子类中的虚函数表 内部 会替换成 自雷的虚函数地址
    当父类的指针或者引用指向子类对象时候,发生多态
    
    
    //如果想扩展新的功能,需要修改源码
    //在真实开发中 提倡开闭原则
    //开闭原则:对扩展进行开发,对修改进行关闭
    
    多态带来的好处
        组织结构清晰
        可读性强
        对于前期和后期的扩展以及维护性高
        
    纯虚函数和抽象类
        在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类函数重写的内容因此可以将虚函数改为
        纯虚函数和抽象类
        
        纯虚函数语法:virtual 返回值类型 函数名 (参数列表) = 0;
        
        当类中有了纯虚函数,这个类也称为抽象类
        
        抽象类特点:
            无法实例化对象
            子类必须重写对象中的纯虚函数。否则也属于抽象类
            
            
    虚析构和纯虚析构
        多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
        解决方式:将父类中的析构函数改为虚析构或者纯虚析构
        
        虚析构和纯虚析构共性:
            可以解决父类指针释放子类对象
            都需要有具体的函数实现
        虚析构和纯虚析构区别:
            如果是纯虚析构,该类属于抽象类,无法实例化对象
        
        虚析构语法
            Victor ~类名(){}
        纯虚析构语法
            Victor ~类名()=0;
        
        总结:
            1、虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
            2、如果子类中没有堆区数据,可以不写位虚析构或纯虚析构
            3、拥有纯虚析构函数的累也属于抽象类
        
        
        
        
    文件
        写文件
            文件操作必须包含文件fstream
            读文件可以利用ofstream,或者fstream类
            打开文件时需要指定操作文件的路径,以及打开方式
            利用<<可以向文件中写数据
            操作完毕,要关闭文件

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值