it编程 > 编程语言 > C/C++

C++构造函数中explicit详解

14人参与 2025-12-03 C/C++

在 c++ 编程中,构造函数是类的核心部分之一。我们常常使用构造函数来初始化对象。但是,如果不加限制,某些构造函数可能会被 隐式调用,从而带来一些意料之外的行为。

为了解决这个问题,c++ 提供了 explicit 关键字。

1. 什么是explicit

在 c++ 中,explicit 关键字用于修饰 单参数构造函数可以看作单参数的构造函数,阻止编译器进行 隐式类型转换拷贝初始化

2. 隐式转换的问题

来看一个例子:

#include <iostream>
using namespace std;

class fraction {
private:
    int numerator;
    int denominator;

public:
    fraction(int num, int den = 1) : numerator(num), denominator(den) {}
    void print() const {
        cout << numerator << "/" << denominator << endl;
    }
};

int main() {
    fraction f1 = 5;  // 隐式调用 fraction(5, 1)
    f1.print();       // 输出:5/1
}

在上面的例子中:

3.explicit的使用示例

基本用法

如果我们在构造函数前加上 explicit

class fraction {
private:
    int numerator;
    int denominator;

public:
    explicit fraction(int num, int den = 1) : numerator(num), denominator(den) {}
    void print() const {
        cout << numerator << "/" << denominator << endl;
    }
};

int main() {
    fraction f1(5);     // ✅ 显式调用,可以
    // fraction f2 = 5; // ❌ 编译错误,不能隐式转换
}

多参数构造函数

有时构造函数有多个参数,但如果除第一个外的参数都有默认值,它依然算作 单参数构造函数,也可能引发隐式转换。

class fraction {
public:
    explicit fraction(int num, int den = 1) { /* ... */ }
};

这里如果没有 explicit,表达式 fraction f = 5; 依然会成立。

4. c++11 之后的扩展

(1)explicit用于转换运算符

在 c++11 之前,类的类型转换函数(比如 operator bool)会允许隐式转换:

class test {
public:
    operator bool() const { return true; }
};

int main() {
    test t;
    if (t) {  // 隐式调用 operator bool()
        cout << "true" << endl;
    }
}

但有时我们并不希望这种隐式转换。c++11 允许写成:

class test {
public:
    explicit operator bool() const { return true; }
};

int main() {
    test t;
    // if (t) { } // ❌ 错误,不能隐式转换
    if (static_cast<bool>(t)) {  // ✅ 必须显式转换
        cout << "true" << endl;
    }
}

(2) c++20 的explicit(bool)

c++20 引入了更灵活的语法:explicit(bool)
这让我们可以根据编译期常量决定是否允许隐式调用。

struct a {
    explicit(true) a(int) {}   // 永远显式
    explicit(false) a(double) {} // 永远允许隐式
};

这种写法在模板编程中很有用。

5. 最佳实践

  1. 几乎总是给单参数构造函数加 explicit
    这样可以避免隐式转换带来的混乱,除非你确实需要这种转换。

  2. 转换运算符应当尽量显式
    尤其是 operator bool,因为隐式转换到 bool 可能导致奇怪的条件判断。

  3. 允许隐式转换的场景
    如果你的类本质上就是包装某个类型(比如 string_view 可以从 const char* 隐式转换),那么允许隐式转换可以让使用更加自然。

总结

补充

到此这篇关于c++构造函数中explicit详解的文章就介绍到这了,更多相关c++构造函数explicit内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

详解C++ 存储二进制数据容器的几种方法

12-03

一文详解C++中的智能指针避坑指南

12-03

C++20新特性之ranges::sort的使用小结

12-03

用c++写控制台贪吃蛇游戏完整步骤

12-05

C++动态数组vector的使用小结

12-02

C++ move 的作用详解及陷阱最佳实践

12-05

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论