explicit、复制构造函数 和 复制函数

本文通过设计三种不同类定义并执行复制初始化与复制操作,揭示了类类型转换、对象初始化过程中的行为与机制。重点分析了复制初始化时的类型转换、场景2中的临时对象生成优化以及场景4中构造函数的隐式与显式调用,提供了深入理解C++对象创建与生命周期的洞察。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文的目的是为摸清类类型转换、对象初始化期间到底发生了什么

设计了3段代码:


class CLASS_TYPE{
public:
    int a;
    CLASS_TYPE(int dd) : a(dd)
    {
        print("fun A ");
    }
    CLASS_TYPE(const CLASS_TYPE & bb)
    {
        a = bb.a;
        print("fun B ");
    }
    CLASS_TYPE & operator=(const CLASS_TYPE & rhs)
    {
        a = rhs.a;
        print("fun C");
    }
};


class CLASS_TYPE{
public:
    int a;
    CLASS_TYPE(int dd) : a(dd)
    {
        print("fun A ");
    }
    explicit CLASS_TYPE(const CLASS_TYPE & bb)
    {
        a = bb.a;
        print("fun B ");
    }
    CLASS_TYPE & operator=(const CLASS_TYPE & rhs)
    {
        a = rhs.a;
        print("fun C ");
    }
};


class CLASS_TYPE{
public:
    int a;
    explicit CLASS_TYPE(int dd) : a(dd)
    {
        print("fun A ");
    }
    CLASS_TYPE(const CLASS_TYPE & bb)
    {
        a = bb.a;
        print("fun B ");
    }
    CLASS_TYPE & operator=(const CLASS_TYPE & rhs)
    {
        a = rhs.a;
        print("fun C ");
    }
};

然后对这3中类定义执行两种复制初始化(一种是从已定义的对象复制初始化,一种是从整形复制初始化),再执行两种复制操作。

结果如下表:

na语句
场景1CLASS_TYPE objb = obja;fun B编译错误fun B
场景2CLASS_TYPE objb = 33;fun A编译错误编译错误
场景3objb = obja;fun Cfun Cfun C
场景4objb = 33;fun A fun Cfun A fun C编译错误


大致结论:

场景3,没什么好说的,直接调用“=”复制操作符


场景4,是在复制时发生类型转换的场景。①的结果表明,先调用了输入参数为int的构造函数,然后调用了复制操作符。因为int参数的构造函数是隐式调用的,所以在③里,这个函数加了explicit后,就不灵光了


场景2,是使用int进行复制初始化的场景。从①的结果看,似乎被转化成了对CLASS_TYPE(int dd)的调用,而和CLASS_TYPE(const CLASS_TYPE & bb)无关,但若和CLASS_TYPE(const CLASS_TYPE & bb)真的一点关系都没有,那②就不应该报错。结合②、③来看,场景2应该是先调用CLASS_TYPE(int dd)生成临时对象tmpobj,然后以tmpobj为参数调用CLASS_TYPE(const CLASS_TYPE & bb)初始化objb。但是为什么运行结果只打印出了fun A呢?估计是生成代码时编译器对这个流程作了优化,把先fun A再fun B的流程优化成了直接调用CLASS_TYPE(int dd)来初始化objb,这样避免了生成临时对象。虽然结果有优化,但编译检查仍然是按照先fun A再fun B的流程来检查的。②、③中分别给funB和funA加了explicit关键字,使得它们不能隐式调用,所以就编译错误了。


场景1,毫无疑问的是,这个场景只调用CLASS_TYPE(const CLASS_TYPE & bb)。但问题是,编译阶段会check几次。很有可能是和场景2一样的原理,但说不准也有可能只check1次。但这已经无关紧要了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值