浅记C++学习之路 基础篇----封装、对象的初始化和清理(接上篇)

目 录


函数的提高


函数默认参数

  • 语法

    返回值类型 函数名(参数 = 默认值)

  • 特性

    若传入参数,则优先使用传入的参数,否则使用默认参数

  • 注意

    如果形参列表中某个参数有默认值,则其后面的所有参数都必须要有默认值

函数占位参数(了解)

  • 语法

    返回值类型 函数名(数据类型)

  • 特性

    占位参数可以有默认值

函数重载

  • 作用

    函数名称相同,提高函数名的复用性

  • 条件

    • 函数名相同
    • 函数在同一作用域
    • 函数参数的 类型不同个数不同顺序不同
  • 注意

    • 函数返回值不可以作为函数重载的条件

    • 引用作为重载条件时,要注意加const和不加const的区别

    • 当函数重载遇到默认参数时,要避免二义性的出现

类和对象


面向对象的特性

  • 万事万物皆为对象,对象有其属性行为

    • 封装

    • 继承

    • 多态

封装

  • 语法

    • class 类名{访问权限:属性/行为};
  • 意义

    • 将属性和行为作为一个整体,表现生活中的事物

    • 将属性和行为加以权限控制

  • 示例1----设计一个圆类求出圆的周长和面积

    #include <iostream>
    
    using namespace std;
    
    #define PI 3.14
    
    //需求:设计一个圆类,求圆的周长和面积
    
    //class代表设计一个类,后面紧跟着的就是类的名称
    class Circle
    {
        //公共访问权限
    public:
        //行为
        //设置半径
        void setRadius(int radius);
        //求周长
        double getCircumference(void);
        //求面积
        double getArea(void);
    
        //私有访问权限
    private:
        //属性
        //半径
        int radius;
    };
    
    int main()
    {
        //通过圆类实例化一个圆对象
        Circle c1;
    
        //设置圆的半径
        c1.setRadius(10);
    
        //求圆的周长和面积并打印
        cout << "圆的周长:" << c1.getCircumference() << endl << "圆的面积:" << c1.getArea() << endl;
    
        return 0;
    }
    
    //设置圆的半径
    void Circle::setRadius(int radius)
    {
        this->radius = radius;
    }
    
    //计算圆的周长
    double Circle::getCircumference(void)
    {
        return 2 * PI * this->radius;
    }
    
    //计算圆的面积
    double Circle::getArea(void)
    {
        return PI * this->radius * this->radius;
    }
    
    

    运行结果:
    在这里插入图片描述

  • 成员访问权限

    • public(公有权限)
      • 类内可以访问,类外可以访问
    • protected(保护权限)
      • 类内可以访问 ,类外不可以访问
      • 子类可以访问
    • private(私有权限)
      • 类内可以访问 ,类外不可以访问
      • 子类不可以访问
      • 一般都把成员属性设置为私有权限,然后在公有部分提供访问接口(成员函数)
        • 优点
          1. 可以自己控制读写权限
          2. 对于写,可以检测数据的有效性
  • 示例2----设计一个立方体类求出立方体的面积和体积

    #include <iostream>
    
    using namespace std;
    
    //需求:设计一个立方体类,求出立方体的面积和体积
    
    //创建一个立方体类
    class Cube
    {
    public:     //公有权限
        void setLength(int length); //设置长
        int getLength(void);        //获取长
    
        void setWidth(int length);  //设置宽
        int getWidth(void);         //获取宽
    
        void setHeight(int length); //设置高
        int getHeight(void);        //获取高
    
        int getArea(void);          //获取面积
        int getVolume(void);        //获取体积
    protected:  //保护权限
    
    private:    //私有权限
        int length; //长
        int width;  //宽
        int height; //高
    };
    
    int main()
    {
        //实例化一个立方体对象
        Cube c1;
    
        //设置立方体的长宽高
        c1.setLength(20);
        c1.setWidth(10);
        c1.setHeight(30);
    
        //打印立方体的长宽高
        cout << "长:" << c1.getLength() << endl << "宽:" << c1.getWidth() << endl << "高:" << c1.getHeight() << endl;
    
        //计算立方体的面积和体积并打印
        cout << "面积:" << c1.getArea() << endl << "体积:" << c1.getVolume() << endl;
    
        return 0;
    }
    
    //设置长
    void Cube::setLength(int length)
    {
        this->length = length;
    }
    //获取长
    int Cube::getLength(void)
    {
        return this->length;
    }
    
    //设置宽
    void Cube::setWidth(int width)
    {
        this->width = width;
    }
    //获取宽
    int Cube::getWidth(void)
    {
        return this->width;
    }
    
    //设置高
    void Cube::setHeight(int height)
    {
        this->height = height;
    }
    //获取高
    int Cube::getHeight(void)
    {
        return this->height;
    }
    
    //获取面积
    int Cube::getArea(void)
    {
        return (this->length*this->width + this->length*this->height + this->width*this->height) * 2;
    }
    //获取体积
    int Cube::getVolume(void)
    {
        return this->length * this->width * this->height;
    }
    
    

    运行结果:
    在这里插入图片描述

  • 类占用空间的计算

    • 成员函数放在公共代码区,不占用类的空间
    • 类占用的空间实际上是成员属性所占用空间之和,但是要注意内存对齐
    • 特别地,对于空类,编译器会分配一个字节空间来唯一标识这个类(占位作用)

今天的C++就学到这里叭,又是学习的一天~

----2023/08/30

对象的初始化和清理

  • 构造函数和析构函数
    • 构造函数
      • 作用
        • 创建对象时为对象的成员属性赋值
      • 语法
        • 类名(){}
      • 规则
        • 函数名与类名相同
        • 没有返回值,可以有参数
        • 可以发生重载
    • 析构函数
      • 作用
        • 对象销毁前执行一些清理工作
      • 语法
        • ~类名(){}
      • 规则
        • 函数名与类名相同,但是前面要加一个~
        • 没有返回值,不可以有参数
        • 不可以发生重载
    • 特性
      • 由编译器自动调用,不需要手动调用,且每个对象只调用一次
      • 构造函数和析构函数都是必须要有的实现,如果我们不提供,编译器会自动生成,其函数内部是空实现
  • 构造函数的分类和调用方法
    • 分类
      • 按参数分类
        • 有参构造
        • 无参构造(不需要传递参数的构造也称默认构造
      • 按类型分类
        • 普通构造
        • 拷贝构造
    • 调用方法
      • 括号法

        //括号法
        Person p1;      //默认构造的调用,注意:不能加(),否则编译器会认为这是一个函数的声明
        Person p2(10);  //有参构造的调用
        Person p3(p2);  //拷贝构造的调用
        
      • 显式法

        //显式法
        Person p4;              //默认构造的调用,注意:不能加(),否则编译器会认为这是一个函数的声明
        Person p5 = Person(10); //有参构造的调用
        Person p6 = Person(p5); //拷贝构造的调用
        
        Person(10); //单独写就是匿名对象,语句结束后系统会立即回收匿名对象
        
        • 通过匿名对象显式的告诉编译器要调用哪种构造
        • 注意
          • 匿名对象的语句结束后系统会立即回收匿名对象
          • 不能利用拷贝构造函数初始化一个匿名对象,否则编译器会认为是对象的声明,导致变量重定义报错
      • 隐式转换法

        //隐式转换法
        Person p7;      //默认构造的调用,注意:不能加(),否则编译器会认为这是一个函数的声明
        Person p8 = 10; //相当于写了 Person p8 = Person(10); //有参构造
        Person p9 = p8; //拷贝构造
        
      • 注意

        • 调用默认构造函数时不要加(),否则编译器会认为这是一个函数的声明
    • 完整示例代码
      #include <iostream>
      
      using namespace std;
      
      class Person
      {
      public:
          //无参构造(只要不需要传递参数的构造都称为默认构造)
          Person()
          {
              cout << "Person 的无参构造函数调用" << endl;
          }
      
          //有参构造
          Person(int age)
          {
              cout << "Person 的有参构造函数调用" << endl;
          }
      
          //拷贝构造
          Person(const Person& p) //构造函数不能修改传进来的参数,必须要用引用传递,如果使用值传递会造成无限递归导致程序崩溃
          {
              this->age = p.age;
              cout << "Person 的拷贝构造函数调用" << endl;
          }
      
          //析构
          ~Person()
          {
              cout << "Person 的析构函数调用" << endl;
          }
      protected:
      
      private:
          int age;
      };
      
      int main()
      {
          //构造函数的调用方法
          //括号法(常用)
          Person p1;      //默认构造的调用,注意:不能加(),否则编译器会认为这是一个函数的声明
          Person p2(10);  //有参构造的调用
          Person p3(p2);  //拷贝构造的调用
      
          //显式法
          Person p4;              //默认构造的调用,注意:不能加(),否则编译器会认为这是一个函数的声明
          Person p5 = Person(10); //有参构造的调用
          Person p6 = Person(p5); //拷贝构造的调用
      
          Person(10); //单独写就是匿名对象,语句结束后系统会立即回收匿名对象
      
          //隐式转换法
          Person p7;      //默认构造的调用,注意:不能加(),否则编译器会认为这是一个函数的声明
          Person p8 = 10; //相当于写了 Person p8 = Person(10); //有参构造
          Person p9 = p8; //拷贝构造
      
          return 0;
      }
      
      
  • 拷贝构造函数的调用时机
    • 使用一个已经创建完毕的对象来初始化另一个对象
    • 值传递的方式给函数参数传值
    • 以值的方式返回局部对象
    #include <iostream>
    
    using namespace std;
    
    class Person
    {
    public:
        Person()
        {
            cout << "Person 的默认构造函数调用" << endl;
        }
    
        Person(int age)
        {
            this->age = age;
            cout << "Person 的有参构造函数调用" << endl;
        }
    
        Person(const Person& p)
        {
            this->age = p.age;
            cout << "Person 的拷贝构造函数调用" << endl;
        }
    
        ~Person()
        {
            cout << "Person 的析构函数调用" << endl;
        }
    protected:
    
    private:
        int age;
    };
    
    void test01(Person p)
    {
    
    }
    
    Person test02(void)
    {
        Person p;
    
        return p;
    }
    
    int main()
    {
        //拷贝构造函数的调用时机
        //使用一个已经创建完毕的对象来初始化另一个对象
        Person p1(20);
        Person p2(p1);
    
        //值传递的方式给函数参数传值
        Person p3;
        test01(p3);
    
        //以值的方式返回局部对象
        Person p4 = test02();
    
        return 0;
    }
    
    
  • 构造函数的调用规则
    作者乏了!!!待续…

不迈出第一步,你永远不知道你能走到哪里,加油!

2023/08/31

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值