C++ explicit关键字讲解

C++ explicit关键字讲解

一、explicit关键字的定义

explicit 关键字被设计用来防止由编译器隐式执行的自动类型转换。当我们在类中声明构造函数时使用了关键字 explicit,编译器在初始化时不会自动转换参数类型,需要我们在构造函数中显式的进行转换。该关键字只能用于一个参数的构造函数,当构造函数需要多个参数时,不需要使用这个关键字,因为编译器无法进行多个类型的隐式转换。

例如,假设我们有以下类定义:

class Test{
public:
    Test(int value): num(value) {}
private:
    int num;
};

如果我们在创建这个类的对象时,使用了一个其他类型的值,比如一个字符串类型,会发生以下隐式类型转换:

Test t = "hello";

在上述代码中,虽然我们的构造函数声明中只有一个整型参数,但是编译器会自动将字符串转换为整数类型,然后传递给构造函数进行初始化。这种行为可能会导致我们在编码时出现错误。如果我们想保证类型的安全,应该使用 explicit 关键字将构造函数定义为显式转换构造函数,禁止编译器进行自动类型转换操作。

二、示例说明

接下来我们通过两个示例来说明explicit的使用方法和效果。

示例一

在这个示例中,我们创建了一个名为 Person 的类,其中有名为 Person(const std::string& name) 的构造函数。我们在这个构造函数前加上 explicit 关键字,从而禁止了编译器的隐式类型转换。

#include <iostream>
#include <string>

class Person {
public:
    explicit Person(const std::string& name) :m_Name(name) {}

    std::string getName() const {
        return m_Name;
    }

private:
    std::string m_Name;
};

void printPerson(const Person& person) {
    std::cout << person.getName() << std::endl;
}

int main() {
    // 正确做法:显式的转换类型
    Person person1 = Person(std::string("Mike"));
    printPerson(person1);

    // 错误做法:隐式的转换类型
    Person person2 = "John";
    printPerson(person2); // 编译报错

    return 0;
}

在上述代码中,我们定义了一个名为 Person 的类,这个类有一个名为 getName() 的函数,返回实例的名称。我们在 Person 的构造函数前加上了 explicit 关键字,从而禁止了编译器的隐式类型转换。在主函数中,我们显式地创建了一个 Person 的实例,然后调用 printPerson() 函数输出其名称。然后我们尝试使用隐式类型转换创建了另一个实例,从而使其编译失败。

示例二

在这个示例中,我们创建了一个名为 Book 的类,其中有一个名为 Book(float price) 的构造函数。然后我们定义了一个名为 printPrice() 的函数,用于输出书的价格。在主函数中,我们使用 explicit 关键字将之前的构造函数定义为显式构造函数,从而禁止了编译器的隐式类型转换。

#include <iostream>

class Book {
public:
    explicit Book(float price) :m_Price(price) {}

    float getPrice() const {
        return m_Price;
    }

private:
    float m_Price;
};

void printPrice(const Book& book) {
    std::cout << book.getPrice() << std::endl;
}

int main() {
    Book book1(10.0);
    printPrice(book1);

    Book book2 = Book(15.0);
    printPrice(book2);

    // 错误做法:隐式的转换类型
    //Book book3 = 20.0f;
    //printPrice(book3); // 编译报错

    // 正确做法:显式的转换类型
    Book book4 = Book(20.0f);
    printPrice(book4);

    return 0;
}

在上述代码中,我们定义了一个名为 Book 的类,这个类有一个名为 getPrice() 的函数,返回实例的价格。我们在 Book 的构造函数前加上了 explicit 关键字,从而禁止了编译器的隐式类型转换。在主函数中,我们先分别使用两种方式创建了两个 Book 实例,然后尝试使用隐式类型转换创建了第三个实例,从而使其编译失败。随后我们又使用了显式类型转换创建了第四个实例,从而成功输出了书的价格。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ explicit关键字讲解 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • vue.js学习之递归组件

    下面是关于vue.js学习递归组件的完整攻略。 什么是递归组件? 递归组件是指在模板内部使用组件本身。在 Vue.js 中,可以通过在组件定义中使用 “name” 选项来使组件可以递归地调用自己。 递归组件的应用场景 递归组件是解决树形结构问题的有效方式。常见的应用场景有无限级分类选择器、评论列表、目录结构等。 递归组件示例1:实现无限级分类选择器 首先,我…

    other 2023年6月27日
    00
  • Spring源码解析之BeanPostProcessor知识总结

    让我来为您详细讲解“Spring源码解析之BeanPostProcessor知识总结”的完整攻略。 一、前言 BeanPostProcessor是Spring中一个非常重要的接口,在Spring容器中扮演着重要角色。BeanPostProcessor用来在Spring容器实例化Bean并自动装配完成后,对Bean进行一些自定义的处理操作,如修改Bean的属性…

    other 2023年6月26日
    00
  • 基于Eclipse中SVN图标不显示的解决方法

    基于Eclipse中SVN图标不显示的解决方法攻略 当在Eclipse中使用SVN插件时,有时候可能会遇到SVN图标不显示的问题。这可能是由于插件配置问题或者Eclipse本身的问题导致的。下面是解决这个问题的完整攻略。 步骤一:检查插件配置 打开Eclipse,点击菜单栏的 \”Window\”(窗口)选项。 选择 \”Preferences\”(首选项)…

    other 2023年8月3日
    00
  • mysql为字段添加和删除唯一性索引(unique) 的方法

    为字段添加唯一性索引可以保证该字段值的唯一性,避免出现重复的数据。下面介绍 MySQL 对字段添加和删除唯一性索引的方法。 添加唯一性索引 添加唯一性索引的语法 添加唯一性索引的语法如下: ALTER TABLE table_name ADD CONSTRAINT constraint_name UNIQUE (column_name); 其中,table_…

    other 2023年6月25日
    00
  • Android手机联系人带字母索引的快速查找

    Android手机联系人带字母索引的快速查找攻略 在Android手机上,联系人带字母索引的快速查找功能可以帮助您快速定位和浏览联系人列表。以下是详细的攻略,包括设置和使用示例。 设置字母索引 打开手机的联系人应用程序。 在联系人列表页面,找到设置图标(通常是一个齿轮或三个垂直点)并点击它。 在设置菜单中,寻找“字母索引”或类似的选项,并确保它处于启用状态。…

    other 2023年8月25日
    00
  • android延迟执行

    Android延迟执行 在 Android 应用开发中,我们可能需要在一定的时间间隔后再执行某些操作,例如延迟启动某个Activity、延迟发出网络请求等。在这种情况下,我们可以使用 Android 提供的一些延迟执行相关的 API。 Handler Android 中的 Handler 类可以用于在指定的时间后发送一条延迟消息。 Handler mHand…

    其他 2023年3月28日
    00
  • 基于jquery封装的一个js分页

    下面是基于jQuery封装的一个JS分页的攻略,包含以下几个步骤: 1. 目录结构 一般来说,我们需要在项目中新建一个js文件夹,然后在这个文件夹下新建一个名为paging.js的文件。 2. HTML页面 在需要分页的页面中,我们需要设置一个DOM元素作为容器,用于渲染分页条。例如,我们可以在页面底部放置一个ID为“pagination”的DIV元素。然后…

    other 2023年6月25日
    00
  • C语言链表与单链表详解

    C语言链表与单链表详解 什么是链表 链表是由一系列节点组成的线性结构,每个节点由两个部分组成:数据域和指针域。数据域用来存储节点的数据,指针域用来指向下一个节点的地址,也就是说每个节点保存了下一个节点的地址信息。由此构成的链式结构被称为链表。 链表相对于数组来说,其大小可以动态调整,插入和删除元素操作更加高效。 单链表 单链表是链表的一种,每个节点中只包含一…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部