explicit

在C++中,explicit是一个非常重要的关键字,主要用在类的构造函数前面,用来控制类对象的隐式转换行为。下面我会用通俗易懂的方式详细说明它的作用、常见的用法,以及为什么要使用它。


一、基本概念:什么是explicit

  • 没有explicit的构造函数,在某些情况下,编译器会允许隐式转换,让某个类型的对象自动转换为另一种类型,或者用一个参数的构造函数把值“自动”变成对象。

  • **加上explicit**后,就会禁止这种隐式的转换,只能“显式”调用,比如用构造函数去创建对象,不能让编译器自己帮你“变”。

简单比喻:

想象你买东西(把值变成对象),

没有explicit,老板(编译器)可以直接帮你把钱(值)自动转成商品(对象),无需你特别说明。

explicit,你就得自己明确说“请帮我用这个钱买个商品”。


二、具体的例子说明

例子1:没有explicit的构造函数

复制代码

#include 
using namespace std;

class MyClass {
public:
    MyClass(int x) { // 普通的构造函数
        cout << "MyClass(int) 被调用,x = " << x << endl;
    }
};

void func(MyClass obj) {
    cout << "函数调用" << endl;
}

int main() {
    func(10);  // 编译器允许隐式转换:把10变成MyClass(10)
    return 0;
}

输出:

复制代码

MyClass(int) 被调用,x = 10
函数调用

这里,虽然func参数是MyClass,但我们用整数10作为参数,编译器会自动帮你调用MyClass(10),达到“隐式转换”的效果。


例子2:加上explicit的构造函数

复制代码

#include 
using namespace std;

class MyClass {
public:
    explicit MyClass(int x) { // 注意加了explicit
        cout << "MyClass(int) 被调用,x = " << x << endl;
    }
};

void func(MyClass obj) {
    cout << "函数调用" << endl;
}

int main() {
    // func(10); // 这是不允许的,会报错
    func(MyClass(10)); // 必须显式调用
    return 0;
}

结果:

  • 编译会出错:

    error: cannot convert ‘int’ to ‘MyClass’ in argument passing

  • 你必须写:func(MyClass(10));,明确指出用MyClass(10)创建对象。


三、总结:explicit的作用

  • 限制隐式转换

    禁止用一个参数的构造函数自动把值变成对象。

  • 让代码更安全、更清楚

    避免“意外”的自动转换带来的潜在错误。

  • 推荐用法

    当你不希望你的类在遇到单参数构造函数时被自动转换,就用explicit


四、什么时候应当使用explicit

  • 当只希望通过直接指定方式(MyClass obj(42);MyClass obj = MyClass(42);)创建对象,而避免被自动转换。
  • 当你的构造函数只负责初始化,不希望发生隐式类型转换。

五、补充:C++11和explicit的高级用法

自C++11起,explicit还能限定在其他操作上,比如:静态工厂方法,也可以用explicit。但核心作用还是阻止隐式转换。


总结一句话

在C++中,explicit用在类的构造函数前面,目的就是阻止让编译器自动帮你把某个类型转换成你的类对象,从而让代码更明确、更安全。

你可能感兴趣的:(explicit)