• 单、多参数构造函数的隐式类型转换


    单、多参数构造函数的隐式类型转换

    前言

    ​ 在C++中,构造函数不仅用于初始化对象的状态,还可以实现隐式类型转换。单参数和多参数构造函数的隐式类型转换为程序员提供了更大的灵活性和便利性。通过合理地利用这些特性,我们可以编写出更加优雅和易于维护的代码。


    1. 单参数构造函数

    ​ 考虑一个表示距离的类Distance,我们可以通过单参数构造函数实现从整数到距离对象的隐式转换。这种转换使得代码更加简洁和直观。

    class Distance
    {
    public:
    	Distance(int meters = 0) :m_meters(meters){}
    
    	void display() const
    	{
    		std::cout << "Distance: " << m_meters << " meters" << std::endl;
    	}
    private:
    	int m_meters;
    };
    void test1()
    {
    	Distance d1 = 100;	// 隐式类型转换
        // 利用整形100创建一个临时Distance变量,再拷贝构造给d1对象 =》部分编译器优化合二为一
    	d1.display();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    这里看似是 “=” 赋值的过程,实际上是一种拷贝构造并非调用赋值运算符。

    通过上面VS2022环境下实际运行可以观察确认 Distance d1 = 100; 语句创建了临时变量,调用了拷贝构造函数(由于编译器优化,省去了拷贝构造的过程)。

    另外一种角度验证临时变量的产生:

    首先我们来看一个编译阶段报错的案例:

    void test1()
    {
    	Distance& d3 = 500;
    	const Distance& d4 = 500;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    报错信息:

    在这里插入图片描述

    在这里插入图片描述

    为什么同为引用对象类型,被 const 修饰的 d4 引用对象就不会报错呢?因为临时变量具有常性!这里d3、d4都是对隐式类型转换生成的对象作引用,而该对象又是临时对象,所以未经 const 修饰的引用语句会报错。

    这显然与 Distance d1 = 100; 会出现临时对象的结论相吻合。

    2. 多参数构造函数

    下面是一个带有多参数构造函数的示例,演示了如何在构造函数中执行隐式类型转换:

    class Time
    {
    public:
    	Time(int hour = 8, int minute = 0, int second = 0):m_hour(hour), m_minute(minute), m_second(second){}
    
    	void print()const
    	{
    		printf("%2d:%2d:%2d\n", m_hour, m_minute, m_second);
    	}
    private:
    	int m_hour;
    	int m_minute;
    	int m_second;
    };
    void test2()
    {
    	// C++11起支持多参数构造函数的隐式类型转换(大括号初始化)
    	Time t = {9, 20, 0};
    	t.print();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这个示例中,我们使用了C++11中的初始化列表语法,将{9, 20, 0}传递给Time对象的构造函数。编译器会自动进行类型转换,将整数转换为Time对象。

    运行结果:

    在这里插入图片描述

    3. explicit 关键字

    当我们希望禁止编译器执行隐式类型转换,可以使用explicit关键字:

    单参数构造函数:

    class Distance
    {
    public:
    	explicit Distance(int meters = 0) :m_meters(meters){}	// 注意这里添加了explicit关键字
    
    private:
    	int m_meters;
    };
    void test1()
    {
    	Distance d1 = 100;		// 隐式类型转换(此时编译报错)
    	Distance d2 = Distance(100);	// 显式类型转换
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    多参数构造函数:

    在这里插入图片描述

    通过使用explicit关键字,可以明确指示编译器在这种情况下产生错误,从而帮助我们避免潜在的错误和歧义。


    总结

    ​ 通过本文的介绍,我们深入了解了单参数和多参数构造函数的隐式类型转换技术。合理地利用这些特性可以使我们的代码更加简洁、清晰,并提高可读性。在编写C++代码时,我们应该根据具体的需求和场景,灵活运用这些技术,从而提高代码的质量和可维护性。

    在这里插入图片描述

  • 相关阅读:
    第143篇 solidity 中的 error-revert
    高通SDX12:SFE(shortcut-fe)软加速驱动效果调测
    MySQL增删查改(初阶)
    导航【操作系统】
    计算机毕业设计 基于SpringBoot+Vue的财务管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    nacos-springboot搭建
    CI2454集成2.4G收发SOC【遥控;灯具;玩具】技术开发资料
    [数据库]数据管理技术的发展阶段
    IntelliJ IDEA 插件推荐
    水文中的Top-Down和bottom-up
  • 原文地址:https://blog.csdn.net/2301_78694061/article/details/136309207