【C++学习笔记】explicit禁止隐式类型转换

本文探讨了C++中对象赋值与构造的过程,包括已存在对象赋值与构造临时对象的情况,并分析了编译器优化的影响。

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

1、对已经存在的对象的赋值

#include "iostream"
using namespace std;
class A {
public:
    A(int a) :_a(a)
    {
        cout << "A(int a)" << endl;
    }

    A(const A& a) {
        cout << "A(const A& a)" << endl;
        _a = a._a;
    }

    A& operator=(const A& a) {
        cout << "operator=(const A& a)" << endl;
        if (&a != this) {
            _a = a._a;
            return *this;
        }
    }

public:
    int _a;
};

int main() {
    A a1(1);
    A a2(2);
    a1 = 10;
    return 0;
}

// 输出:
//A(int a)
//A(int a)
//A(int a)
//operator=(const A& a)

会先用 10 进行构造一个匿名对象,然后调用赋值重载对已经存在的a1进行赋值。

2、对不存在的对象赋值进行构造

先看一个现象:

#include "iostream"
using namespace std;
class A {
public:
    A(int a) :_a(a)
    {
        cout << "A(int a)" << endl;
    }

    A(const A& a) {
        cout << "A(const A& a)" << endl;
        _a = a._a;
    }

    A& operator=(const A& a) {
        cout << "operator=(const A& a)" << endl;
        if (&a != this) {
            _a = a._a;
            return *this;
        }
    }

public:
    int _a;
};

int main() {
    A a1 = A(2);
    return 0;
}

//输出:
//A(int a)

按道理是先构造了一个匿名对象,然后再对 a1 调用拷贝构造来构造对象,但是这里很明显编译器优化了,直接进行一次构造。

因此 main 中改成:

int main() {
    A a1 = 10;
    return 0;
}

得到的结果与上面一致,只调用一次的构造函数。因为这里也是先利用10 构造一个匿名函数,然后进行拷贝构造。

当然上述的操作在加了explicit后都不可以了

禁止隐式类型转换,禁止的是一个操作数在进行运算符操作时,利用构造函数升级成这个类
比如,上述10,在与A这个类型的对象进行运算符操作时,通过构造函数升级成A类型的匿名对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值