• 【C++】构造函数调用规则 ( 默认构造函数 | 默认无参构造函数 | 默认拷贝构造函数 | 构造函数调用规则说明 )






    一、默认构造函数



    C++ 类中 2 种特殊的构造函数 , 分别是 :

    • 默认无参构造函数 : 如果 C++ 类中 没有定义构造函数 , C++ 编译器会自动为该类提供一个 " 默认的无参构造函数 " , 函数体为空 , 不做任何操作 ;
    • 默认拷贝构造函数 : 如果 C++ 类中 没有定义拷贝构造函数 , C++ 编译器会自动为该类提供一个 " 默认的拷贝构造函数 " , 在函数中对成员变量进行简单的复制操作 ;

    1、默认无参构造函数


    如果 C++ 类中 没有定义构造函数 , C++ 编译器会自动为该类提供一个 " 默认的无参构造函数 " , 函数体为空 , 不做任何操作 ;

    • 没有定义构造函数 : 如果 没有为 C++ 类定义 构造函数 , C++ 编译器 将自动为该类 生成一个默认的无参构造函数 ;
    • 定义了构造函数 : 如果为 C++ 类 定义了其他类型的构造函数 ( 有参构造函数 / 无参构造函数 / 拷贝构造函数 ) , C++ 编译器 将不再自动生成默认的无参构造函数 ;

    默认构造函数内容 : C++ 编译器 为类 定义的 默认无参构造函数 , 其函数体为空 , 如下代码所示 ;

    class MyClass {  
    public:  
        int x;  
        // 默认构造函数  
        MyClass() {
        }  
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    下面的代码 , 会自动调用 默认的 无参构造函数 ;

    MyClass obj; // 调用 默认 构造函数
    
    • 1

    2、默认拷贝构造函数


    " 默认拷贝构造函数 " 用于创建一个新对象作为现有对象的副本 , 其作用是将 现有对象 的成员变量 复制到 新对象中 ;

    创建一个类对象 并将其 赋值给 另一个类对象时 , 会自动调用 默认拷贝构造函数 ;


    如果 C++ 类中 没有定义拷贝构造函数 , C++ 编译器会自动为该类提供一个 " 默认的拷贝构造函数 " , 在函数中对成员变量进行简单的复制操作 ;

    • 没有定义拷贝构造函数 : 如果 没有为 C++ 类定义 拷贝构造函数 , C++ 编译器 将自动为该类 生成一个 默认的拷贝构造函数 ;
    • 定义了拷贝构造函数 : 如果为 C++ 类 定义了 拷贝构造函数 , C++ 编译器 将不再自动生成默认的拷贝构造函数 ;

    默认拷贝构造函数内容 : C++ 编译器 为类 定义的 默认拷贝构造函数 , 在函数内部将 现有对象 的 成员变量 逐个赋值给 新对象 ;

    class MyClass {  
    public:  
        int x;  
        // 默认拷贝构造函数  
        MyClass(const MyClass& other) {  
            x = other.x;  
        }  
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    下面的代码 , 第一行代码会自动调用默认的无参构造函数 , 第二行代码会自动调用默认的拷贝构造函数 ;

    MyClass obj; 			// 调用默认无参构造函数
    MyClass obj2 = obj; 	// 调用默认拷贝构造函数
    
    
    • 1
    • 2
    • 3




    二、构造函数调用规则




    1、构造函数规则说明


    构造函数调用规则 :

    • 提供 默认无参构造函数 和 默认拷贝构造函数 : 如果 C++ 类中 没有定义 构造函数 时 , C++ 编译器 会提供 默认的 无参构造函数 和 默认的 拷贝构造函数 ;
    • 提供 默认拷贝构造函数 : 如果 C++ 类中 , 定义了 非拷贝构造函数 , 如 : 有参构造函数 / 无参构造函数 , C++ 编译器 不会提供 默认的无参构造函数 , 但是 会提供 默认的 拷贝构造函数 ;
      • 默认的 拷贝构造函数 只能进行 成员变量的 复制 ;
    • 特例 : 如果 C++ 类中 , 定义了 拷贝构造函数 , 那么 C++ 编译器不会提供 默认的无参构造函数 ;

    2、代码示例 - 只定义拷贝构造函数


    下面的代码中 , 定义了 拷贝构造函数 , C++ 编译器不会自动生成 默认的无参构造函数 和 默认的拷贝构造函数 ;

    使用 Student s; 代码 创建对象 , 报错 “Student”: 没有合适的默认构造函数可用 ;

    说明 C++ 编译器没有为该类生成 默认的无参构造函数 ;


    代码示例 :

    #include "iostream"
    using namespace std;
    
    class Student
    {
    public:
    	Student(const Student& s)
    	{
    		m_age = s.m_age;
    		m_height = s.m_height;
    		cout << "调用拷贝构造函数" << endl;
    	}
    
    public:
    	int m_age;		// 年龄
    	int m_height;	// 身高
    };
    
    
    int main()
    {
    	// 定义了拷贝构造函数 不再生成默认无参构造函数
    	Student s;
    
    
    	// 控制台暂停 , 按任意键继续向后执行
    	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

    执行结果 :

    已启动生成…
    1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
    1>hello_world.cpp
    1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(23,10): error C2512: “Student”: 没有合适的默认构造函数可用
    1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(4,7): message : 参见“Student”的声明
    1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
    ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0==========
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述


    3、代码示例 - 只定义有参构造函数


    下面的代码中 , 定义了 有参构造函数 , C++ 编译器不会自动生成 默认的无参构造函数 和 默认的拷贝构造函数 ;

    使用 Student s; 代码 创建对象 , 报错 “Student”: 没有合适的默认构造函数可用 ;

    说明 C++ 编译器没有为该类生成 默认的无参构造函数 ;


    代码示例 :

    #include "iostream"
    using namespace std;
    
    class Student
    {
    public:
    	// 带参构造函数
    	Student(int age, int height)
    	{
    		m_age = age;
    		m_height = height;
    		cout << "调用带参数构造函数 m_age = " << m_age << endl;
    	}
    
    	Student(const Student& s)
    	{
    		m_age = s.m_age;
    		m_height = s.m_height;
    		cout << "调用拷贝构造函数" << endl;
    	}
    
    public:
    	int m_age;		// 年龄
    	int m_height;	// 身高
    };
    
    
    int main()
    {
    	// 定义了拷贝构造函数 不再生成默认无参构造函数
    	Student s;
    
    
    	// 控制台暂停 , 按任意键继续向后执行
    	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

    执行结果 :

    已启动生成…
    1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
    1>hello_world.cpp
    1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(31,10): error C2512: “Student”: 没有合适的默认构造函数可用
    1>D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\hello_world.cpp(4,7): message : 参见“Student”的声明
    1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
    ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0==========
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

  • 相关阅读:
    部署java程序的服务器cpu过高如何排查和解决
    iOS 关于键盘监听
    Hbase
    vue如何实现多页面应用网页
    Spring、Spring MVC、Spring boot、Spring Cloud面试题(史上最全面试题,精心整理100家互联网企业,面试必过)
    学习顺序表,Java实现
    MongoDB深度学习
    Linux性能测试之性能测试指标详解
    一台电脑安装多个不同版本Python
    【数据库之postgreSQL】全文索引之飞快
  • 原文地址:https://blog.csdn.net/han1202012/article/details/132896007