C++ explicit 关键字的使用

2024 年 8 月 29 日 | 阅读 3 分钟

在本文中,我们将通过示例讨论 C++ 中的 explicit 关键字。

explicit 关键字在 C++ 中与构造函数一起使用,以防止它们进行隐式转换。C++ 的 explicit 构造函数被标记为不进行隐式类型转换。这一点很重要,因为隐式转换经常会产生意想不到的后果。如果一个类中有一个带单个参数的构造函数,该构造函数会将这个单一参数转换为所创建的类,从而成为一个转换构造函数。我们在 C++ 中使用 explicit 关键字来避免这种隐式转换。

C++ Explicit 的工作原理

首先,让我们来定义 C++ 中的构造函数。构造函数是 C++ 中的特殊方法。每当创建类对象时,它们都会被自动调用。我们使用构造函数来初始化新对象的数据成员。

现在,我们来看看隐式转换以及如何使用 C++ 的 explicit 关键字来避免它们。它会在我们没有直接指示编译器的情况下发生。将一种数据类型转换为另一种数据类型被称为类型转换(casting)。如果没有 C++ 的 explicit 关键字,编译器可以自动执行转换,从而省去了我们执行类型转换的需要。

通过在构造函数前加上 explicit 关键字,我们告诉编译器不要对该构造函数执行任何隐式转换。我们希望这些构造函数被显式调用,而不是让编译器执行不期望的类型操作。

示例

可以在 C++ 中定义 explicit 构造函数以避免隐式类型转换。当一个构造函数被设为 explicit 时,编译器在使用该构造函数初始化对象时不能进行任何隐式转换。以下是一些使用 explicit 构造函数的 C++ 示例。

示例

输出

number1: 72
number2: 85

说明

  • 在这个示例中,代码定义了一个名为 MyNumber 的类,它封装了一个整数值(number),并提供一个 explicit 构造函数来初始化它。
  • 构造函数 explicit MyNumber(int value) 被声明为 explicit,这意味着它不能用于隐式类型转换。在构造 MyNumber 对象时,它需要显式的类型转换。
  • 在主函数中
  • MyNumber number1(72); 这一行直接用整数值 72 初始化 number1。这是允许的,因为它是直接初始化。
  • MyNumber number2 = MyNumber(85); 它显式地用参数 85 调用构造函数,并用其结果初始化 number2。由于是显式调用构造函数,这也是允许的。
  • MyNumber num3 = 55; 和 MyNumber num4 = 3.14; 这两行被注释掉了,因为它们会导致编译错误。这两行试图执行隐式类型转换,但由于构造函数被声明为 explicit,这是不允许的。我们需要使用显式类型转换来修复这些错误,例如 MyNumber num3(static_cast<int>(55)); 或 MyNumber num4(static_cast<int>(3.14));。
  • 最后,代码使用 std::cout 将存储在 number1 和 number2 中的值打印到控制台。

explicit 关键字的用途

  1. 防止隐式转换: 当一个构造函数被指定为 explicit 时,它会阻止其参数被自动或隐式地转换为类类型。这有助于防止意外且可能容易出错的类型转换。
  2. 对构造函数的严格要求: 我们可以开发对其参数施加特定标准或约束的构造函数。将构造函数声明为 explicit 要求用户指定正确的类型,表明他们了解这些要求。
  3. 避免歧义: 在多个构造函数都可用于初始化的情况下,explicit 关键字可以解决歧义。它帮助编译器根据提供的参数选择合适的构造函数。
  4. 防止意外的对象创建: 一个类可能有一个接受单个参数的构造函数方法,我们希望防止使用此构造函数意外创建实例。