explicit关键字

发布时间 2023-12-12 21:46:16作者: Beasts777

1. 隐式类型转换

在C++11前,对于类的使用,存在隐式类型转化的情况,实质上是构造函数的隐式调用。下面是一个例子:

EG:

  • 代码:

    #include <iostream>
    using namespace std;
    
    class Test {
    public:
        int x;
        int y;
        Test(int x = 1, int y = 2): x(x), y(y){ cout << "parameterized constructor" << endl; }
    };
    
    void func(const Test& t) {
        cout << "x==" << t.x << "\t" << "y==" << t.y << endl;
    }
    
    int main(void){
        Test t1 = 10;
        cout << "x==" << t1.x << "\t" << "y==" << t1.y << endl;
        func(20);
        return 0;
    }
    
    
  • 输出:

    parameterized constructor
    x==10	y==2
    parameterized constructor
    x==20	y==2
    
  • 分析:

    • 第16行:发生隐式类型转化,实际上相当于:Test t1(10)
    • 第18行:发生隐式类型转换,实际上相当于:func(Test(20))

问题:

这样的隐式类型转化,有时可能会导致意想不到的错误,因此从C++11开始,提出了explicit关键字。

2. explict关键字

作用:

指定构造函数或转换函数为显式,即它不能用于隐式转换和复制初始化

EG:

  • 代码:

    #include <iostream>
    using namespace std;
    
    class Test {
    public:
        int x;
        int y;
        explicit Test(int x = 1, int y = 2): x(x), y(y){ cout << "parameterized constructor" << endl; }
    };
    
    void func(const Test& t) {
        cout << "x==" << t.x << "\t" << "y==" << t.y << endl;
    }
    
    int main(void){
        // Test t1 = 10; 		// error
        Test t1(10);
        cout << "x==" << t1.x << "\t" << "y==" << t1.y << endl;
        // func(20);			// error
        func(Test(20));
        return 0;
    }
    
    
  • 分析:

    • 第8行:使用explicit关键字,禁止Test类的隐式转换复制初始化
    • 第16、19行:因为禁止了隐式转换,所以错误。

应用场景:

一般情况下,除了你有进行隐式转化的必要,否则建议使用explicit关键字,这可以增加程序的严谨性。