• 【C++】类的封装 ② ( 封装最基本的表层概念 | 类对象作为参数传递的几种情况 )






    一、类的封装 : 将数据和方法封装到一个类中




    1、封装最基本的表层概念


    将数据和方法封装到一个类中 , 是封装最基础的概念 ;


    类的封装 最基本的功能 就是将 若干数据 和 若干方法 , 封装到一个类中 , 这些数据在内存中以一个整体的形式进行运作 ;

    封装 Encapsulation : 将 数据 和 操作 封装在类中 , 可以将 类 内部的 实现细节 隐藏 , 只暴露有限的 接口 与外部进行交互 , 从而达到保护 类 对象的 内部状态 不被外部随意修改 ;


    将 现实世界 中 存在的 客观事物 封装成 抽象 的 类 , 类 中 包含了 数据 和 操作 ,

    • 只有 可信的 类 或 对象 才能访问 隐藏起来的信息 ;
    • 大部分类默认只能访问 类 公开的接口 ;

    2、代码分析 - 基本封装


    在下面的代码中 , 定义了一个 Circle 类对象 , 其中 封装了 2 个成员属性 ;

    	// 定义属性成员 , 圆的半径
    	double m_r;
    
    	// 定义属性成员 , 圆的面积
    	double m_s;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3 个成员方法 ;

    定义该 Circle 类对象 circle , 则借助 circle 对象 , 可以直接访问其中的 2 个成员属性 和 3 个成员 方法 ;

    	// 获取半径
    	double getR()
    	{
    		return m_r;
    	}
    
    	// 设置半径
    	void setR(double r)
    	{
    		m_r = r;
    	}
    
    	// 获取面积
    	double getS()
    	{
    		m_s = 3.14 * m_r * m_r;
    		return m_s;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3、代码分析 - 类对象作为参数传递的几种情况 ( 指针 / 引用 / 直接 )


    使用 类 对象 作为函数参数时 , 分别讨论下面三种情况 ;

    • 第一种情况 : 使用 类对象 指针作为参数 , 传参时 , 传入的必须是一个指针值 , 也就是地址值 ,
      • 如果将 Circle circle 对象传入 , 必须使用 取地址符 & 获取对象的地址 , 才能传给 void fun1(Circle* circle) 函数 ;
      • 在函数内部调用 circle 对象的成员 , 需要使用 -> 符号调用 , 也就是访问指针内存空间的成员的方式 ;
    // 使用 类对象指针作为参数
    void fun1(Circle* circle) 
    {
    	cout << "fun1(Circle* circle) : " << circle->getS() << endl;
    }
    
    Circle circle;
    // 传递指针必须使用取地址符取地址
    fun1(&circle);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 第二种情况 : 使用 类对象引用作为 参数 ; 传参时 , 可以直接将 circle 对象传入 , 因为 C++ 编译器在编译引用时 , 会自动为 引用参数 添加 & 取地址 , 在函数内部访问时 , 会自动为引用添加 -> 符号访问内存空间数据 , 引用 等价于 一级指针 ;
    // 使用 类对象引用作为参数
    void fun2(Circle& circle)
    {
    	cout << "fun2(Circle& circle) : " << circle.getS() << endl;
    }
    
    Circle circle;
    // 传递引用直接传递即可
    fun2(circle);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 第三种情况 : 直接使用 类对象作为参数 , 这种情况下 , 需要拷贝整个对象作为副本 , 函数调用效率很低 , 不建议使用这种方式 , 该调用方式与 引用 类型参数操作相同 , 推荐使用 引用类型的参数 ;
    // 直接使用 类对象作为参数
    void fun3(Circle circle)
    {
    	cout << "fun3(Circle circle) : " << circle.getS() << endl;
    }
    
    Circle circle;
    // 传递对象直接传递 , 需要拷贝整个对象效率很低
    fun3(circle);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4、完整代码示例


    完整代码示例 :

    // 包含 C++ 头文件
    #include "iostream"
    
    // 使用 std 标准命名空间
    //		该命名空间中 , 定义了很多标准定义
    using namespace std;
    
    // 定义圆形类
    class Circle
    {
    public:
    	// 定义属性成员 , 圆的半径
    	double m_r;
    
    	// 定义属性成员 , 圆的面积
    	double m_s;
    
    public:
    	// 获取半径
    	double getR()
    	{
    		return m_r;
    	}
    
    	// 设置半径
    	void setR(double r)
    	{
    		m_r = r;
    	}
    
    	// 获取面积
    	double getS()
    	{
    		m_s = 3.14 * m_r * m_r;
    		return m_s;
    	}
    };
    
    // 使用 类对象指针作为参数
    void fun1(Circle* circle) 
    {
    	cout << "fun1(Circle* circle) : " << circle->getS() << endl;
    }
    
    // 使用 类对象引用作为参数
    void fun2(Circle& circle)
    {
    	cout << "fun2(Circle& circle) : " << circle.getS() << endl;
    }
    
    // 直接使用 类对象作为参数
    void fun3(Circle circle)
    {
    	cout << "fun3(Circle circle) : " << circle.getS() << endl;
    }
    
    int main()
    {
    	Circle circle;
    	circle.setR(10);
    	cout << "圆面积为 : " << circle.getS() << endl;
    
    	// 传递指针必须使用取地址符取地址
    	fun1(&circle);
    
    	// 传递引用直接传递即可
    	fun2(circle);
    
    	// 传递对象直接传递 , 需要拷贝整个对象效率很低
    	fun3(circle);
    
    	// 控制台暂停 , 按任意键继续向后执行
    	system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    执行结果 :

    圆面积为 : 314
    fun1(Circle* circle) : 314
    fun2(Circle& circle) : 314
    fun3(Circle circle) : 314
    Press any key to continue . . .
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

  • 相关阅读:
    scrapy个人循序渐进
    极米Z6X Pro值得购买吗?这篇评测告诉你
    干货分享 | 速速围观,想要BIM落地,这些应用阶段都不可或缺
    Java 代码 实现 字符串去掉左边空格 字符串去掉右边空格
    L51.linux命令每日一练 -- 第八章 Linux磁盘与文件系统管理命令 -- mkfs和dumpe2fs
    Nuxt服务端请求及获取Cookie
    Kafka - 3.x 文件存储不完全指北
    Centos7安装单机版Kafka
    [图像处理] IOU Intersection over Union
    Linux命令详解
  • 原文地址:https://blog.csdn.net/han1202012/article/details/132745261