• 【C++】拷贝构造函数调用时机 ② ( 对象值作为函数参数 | 对象值作为函数返回值 )


    博客总结 :

    " 拷贝构造函数 " 又称为 " 赋值构造函数 " , 该类型构造函数有 4 种调用时机 ;

    • ① 使用一个对象初始化另外一个对象 : 使用 一个 类实例对象 初始化 另外一个 类实例对象 ;
    	// 使用一个对象初始化另外一个对象
    	// 直接手动 调用拷贝构造函数
    	Student s2 = Student(s1);
    
    • 1
    • 2
    • 3
    • ② 将一个对象赋值给另外一个对象 : 将 一个 类实例对象 赋值给 另外一个 类实例对象 ;
    	// 将一个对象赋值给另外一个对象
    	// 自动调用拷贝构造函数
    	Student s2 = s1;
    
    • 1
    • 2
    • 3
    • ③ 对象值作为函数参数 : 类的实例对象 以值的方式 传递给函数 , 不是以 指针 或 引用 的方式 ;
    // 定义函数, 接收 Student 对象值作为参数
    void fun(Student s)
    {
    }
    
    • 1
    • 2
    • 3
    • 4
    • ④ 对象值作为函数返回值 : 函数直接返回类的实例对象 值 , 不是返回 指针 或 引用 ;
    // 定义函数, 返回 Student 对象值作为返回值
    Student fun()
    {
    	Student s1(18, 170);
    	return s1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6




    一、拷贝构造函数概念




    C++ 语言中的 拷贝构造函数 是 C++ 类中的 特殊构造函数 ,

    其作用是 创建一个新的 类实例对象 , 作为现有实例对象的 拷贝后的副本 ;

    拷贝构造函数 的 主要作用 是初始化新创建的对象 , 使其内容与原对象完全相同 ;






    二、对象值作为函数参数




    1、拷贝构造函数调用情况说明


    类的实例对象 以值的方式 传递给函数 , 不是以 指针 或 引用 的方式 ;


    这种情况 是 以 类的 实例对象 值作为参数 , 与 对象值 相对的是

    • 对象指针
    • 对象引用

    定义函数 void fun(Student s) , 该函数 的 形参是 Student 类型对象 ,

    
    // 定义函数, 接收 Student 对象值作为参数
    void fun(Student s)
    {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果调用该函数 , 需要拷贝实参 , 将 实参的副本值 , 也就是对象值 传递给函数形参 , 这个过程需要调用 Student 类的 拷贝构造函数 ;

    该操作 全程 由 C++ 编译器完成 , 不需要 开发者 手动干预 ;


    2、代码示例 - 对象值作为函数参数


    代码示例 :

    #include "iostream"
    using namespace std;
    
    class Student
    {
    public:
    	Student(int age, int height)
    	{
    		m_age = age;
    		m_height = height;
    		cout << "调用带参数构造函数" << endl;
    	}
    
    	Student(const Student& s)
    	{
    		m_age = s.m_age;
    		m_height = s.m_height;
    		cout << "调用拷贝构造函数" << endl;
    	}
    
    public:
    	int m_age;		// 年龄
    	int m_height;	// 身高
    };
    
    // 定义函数, 接收 Student 对象值作为参数
    void fun(Student s)
    {
    	
    }
    
    int main()
    {
    	// 调用带参数构造函数
    	Student s1(18, 170);
    
    	// 类对象值作为函数参数
    	fun(s1);
    
    
    	// 控制台暂停 , 按任意键继续向后执行
    	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

    执行结果 :

    • 首先 , Student s1(18, 170) 调用带参数构造函数 , 创建 Student 类实例对象 ;
    • 然后 , 将创建的实例对象 传递给 fun 函数 , 传递时由于传递的是 对象值 , 需要拷贝对象副本 , 拷贝副本时会自动调用 Student 类的 拷贝构造函数 ;
    调用带参数构造函数
    调用拷贝构造函数
    Press any key to continue . . .
    
    • 1
    • 2
    • 3

    在这里插入图片描述





    三、对象值作为函数返回值




    1、拷贝构造函数调用情况说明


    函数直接返回类的实例对象 值 , 不是返回 指针 或 引用 ;


    下面的代码 , 定义了函数 , 返回在函数内部创建的 Student 类实例对象 ;

    // 定义函数, 返回 Student 对象值作为返回值
    Student fun()
    {
    	Student s1(18, 170);
    	return s1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    由于 函数作用域结束后 , 其栈内存会被释放 , 在栈内存中的 Student 对象也会被销毁 , 因此 Student 类型的返回值需要返回一个副本 , 这个副本需要调用 拷贝构造函数 创建 ;


    2、代码示例 - 对象值作为函数返回值


    代码示例 :

    #include "iostream"
    using namespace std;
    
    class Student
    {
    public:
    	Student(int age, int height)
    	{
    		m_age = age;
    		m_height = height;
    		cout << "调用带参数构造函数" << endl;
    	}
    
    	Student(const Student& s)
    	{
    		m_age = s.m_age;
    		m_height = s.m_height;
    		cout << "调用拷贝构造函数" << endl;
    	}
    
    public:
    	int m_age;		// 年龄
    	int m_height;	// 身高
    };
    
    // 定义函数, 返回 Student 对象值作为返回值
    Student fun()
    {
    	Student s1(18, 170);
    	return s1;
    }
    
    int main()
    {
    
    	// 类对象值作为函数返回值
    	fun();
    
    
    	// 控制台暂停 , 按任意键继续向后执行
    	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

    执行结果 :

    在这里插入图片描述

  • 相关阅读:
    保险业SAP转型:奠定坚实的基础
    程序员为什么要软一点?
    vue 在什么情况下在数据发生改变的时候不会触发视图更新
    基于HTML家乡旅游主题项目的设计与实现——少林寺(5页)HTML+CSSS
    【SQL】MySQL中的约束
    修改Cpython解释器为python单文件代码加密(无import自己模块)
    mybatis-plus分页查询三种方法
    【大数据】计算引擎:Spark核心概念
    JVM P1 整体架构,类加载器,运行时数据区
    基于多模态融合的非遗图片分类研究
  • 原文地址:https://blog.csdn.net/han1202012/article/details/132864537