首页 > 编程语言 >C++ explicit

C++ explicit

时间:2023-09-18 15:57:17浏览次数:31  
标签:real double imag explicit C++ Complex rhs

C++ explicit

explicit关键字有两个用途:

  1. 指定构造函数或者转换函数(C++11起)为显示,即它不用用于隐式转换和赋值初始化。
  2. 可以与常量表达式一同使用。当该表达式为true才为显示转换(C++20起)。

1.将构造函数标记为显式

C++中的explicit关键字通常用来将构造函数标记为显式类型转换,即在创建对象的时候不能进行隐式转换。
可以通过一个例子理解:

/*************************************************************************
        > File Name: 01.cpp
        > Author:
        > Mail:
        > Created Time: Mon 18 Sep 2023 02:12:16 PM CST
 ************************************************************************/
#include <iostream>
using namespace std;

class Complex {
private:
    double real;
    double imag;

public:
    Complex(double r = 0.0, double i = 0.0)
        : real(r)
        , imag(i)
    {
    }

    bool operator==(Complex rhs)
    {
        return (real == rhs.real && imag == rhs.imag)
                    ? true
                    : false;
    }
};

int main()
{
    Complex com1(3.0, 0.0);

    if (com1 == 3.0)
        cout << "Same" << endl;
    else
        cout << "Not Same" << endl;

    return 0;
}

编译并执行:

ydqun@ydqhost explicit % g++ 01-without-explicit.cpp                                                                                                                                                             [0]
ydqun@ydqhost explicit % ./a.out                                                                                                                                                                                 [0]
Same

在上述例子中,main函数里构建了com1实例,并且用com1和double类型的3.0进行比较,此时double类型的3.0被隐式转换成Complex类型。
我们可以避免这种隐式转换,因为它们可能会导致意外的结果。我们可以通过explicit关键字使构造函数变成显式。例如,如果我们尝试使用以下带有explicit关键字的构造函数,就会出现编译错误。

#include <iostream>
using namespace std;

class Complex {
private:
    double real;
    double imag;

public:
    explicit Complex(double r = 0.0, double i = 0.0)
        : real(r)
        , imag(i)
    {
    }

    bool operator==(Complex rhs)
    {
        return (real == rhs.real && imag == rhs.imag)
                    ? true
                    : false;
    }
};

int main()
{
    Complex com1(3.0, 0.0);

    if (com1 == 3.0)
        cout << "Same" << endl;
    else
        cout << "Not Same" << endl;

    return 0;
}

给构造函数添加了explicit关键字修饰后,此时编译会出现如下错误:

ydqun@ydqhost explicit % g++ 01-without-explicit.cpp                                                                                                                                                             [0]
01-without-explicit.cpp: In function ‘int main()’:
01-without-explicit.cpp:34:14: error: no match for ‘operator==’ (operand types are ‘Complex’ and ‘double’)
   34 |     if (com1 == 3.0)
      |         ~~~~ ^~ ~~~
      |         |       |
      |         Complex double
01-without-explicit.cpp:22:10: note: candidate: ‘bool Complex::operator==(Complex)’
   22 |     bool operator==(Complex rhs)
      |          ^~~~~~~~
01-without-explicit.cpp:22:29: note:   no known conversion for argument 1 from ‘double’ to ‘Complex’
   22 |     bool operator==(Complex rhs)

这时候需要我们进行显式转换。

#include <iostream>
using namespace std;

class Complex {
private:
    double real;
    double imag;

public:
    explicit Complex(double r = 0.0, double i = 0.0)
        : real(r)
        , imag(i)
    {
    }

    bool operator==(Complex rhs)
    {
        return (real == rhs.real && imag == rhs.imag)
                    ? true
                    : false;
    }
};

int main()
{
    Complex com1(3.0, 0.0);

    if (com1 == (Complex)3.0)  //此处对double类型的3.0进行显式转换为Complex
        cout << "Same" << endl;
    else
        cout << "Not Same" << endl;

    return 0;
}

编译并输出:

ydqun@ydqhost explicit % g++ 02-with-explicit.cpp                                                                                                                                                                [0]
ydqun@ydqhost explicit % ./a.out                                                                                                                                                                                 [0]
Same

2.与常量表达式一同使用

explicit关键字可以与常量表达式一起使用。但是,如果常量表达式的计算结果为true,此时构造函数是显式的;否则,构造函数是
隐式的。

#include <iostream>

constexpr bool ENABLE_EXPLICIT = false;

class Foo {
public:
    explicit(ENABLE_EXPLICIT)
    Foo(int i) : m_i(i) {}
private:
    int m_i;
};

int main()
{
    Foo a = 1;
}

编译可以通过,但是如果把变量ENABLE_EXPLICIT改为true,则会出现如下编译错误:

ydqun@ydqhost explicit % g++ 03-explicit.cpp -std=c++2a                                                                                                                                                          [0]
03-explicit.cpp: In function ‘int main()’:
03-explicit.cpp:21:13: error: conversion from ‘int’ to non-scalar type ‘Foo’ requested
   21 |     Foo a = 1;

注意,编译以上例程需要在C++20及以上才能编译通过。

标签:real,double,imag,explicit,C++,Complex,rhs
From: https://www.cnblogs.com/ydqblogs/p/17711948.html

相关文章

  • C++基础入门
    C++基础入门1C++初识1.1第一个C++程序编写一个C++程序总共分为4个步骤创建项目创建文件编写代码运行程序1.1.1创建项目​ VisualStudio是我们用来编写C++程序的主要工具,我们先将它打开1.1.2创建文件右键源文件,选择添加->新建项给C++文件起个名称,然后点击添......
  • java中使用JNA调用C/C++动态链接库中的函数
    目录C++部分创建动态库项目JAVA部分pom依赖工程结构测试类jna提供C与JAVA数据类型映射参考C++部分创建动态库项目注意:动态库中的头文件,必须要将需要导出的函数包裹在extern"C"{}中,否者在使用侧java工程中,就无法加载并使用JAVA部分pom依赖<dependencies><dependenc......
  • C++ Primer 学习笔记——第十章
    第10章前言在前面我们学习容器的时候,是否发现标准库下的对容器的操作并不是太多(或许,初学时已经觉得好多了......
  • 简单分治快排问题解析(c++实现)
    这几天刷了需要使用分治快排思想去解决的几道比较好的题目,所以写下这篇博客用于复习和以后的复盘。什么是分治快排思想首先我们要知道什么是分治快排思想,这个思想其实就是在模拟实现qsort算法的时候使用的一个方法,在模拟实现qsort的时候,我们知道第一步是需要使用一个随意选择(三数取......
  • C++实现论文查重
    软件工程https://edu.cnblogs.com/campus/gdgy/CSGrade21-12/homework/13014作业要求根据给出的样例进行查重,并把结果记录在PSP表格中作业目的对查重有一定的初步了解GitHub链接https://github.com/xingch123456789/3119000414PSP表格PSP2.1Person......
  • Qt/C++音视频开发54-视频监控控件的极致设计
    一、前言跌跌撞撞摸爬滚打一步步迭代完善到今天,这个视频监控控件的设计,在现阶段水平上个人认为是做的最棒的(稍微自恋一下),理论上来说应该可以用5年不用推翻重写,推翻重写当然也是程序员爱干的事情,这个就要考验个人的功底,设计的好框架搭建的好,可以很多年不用变,只需要在现有框架小修......
  • C++智能指针
    智能指针是C++语言中一种方便、安全的内存管理工具。智能指针可以自动管理对象的生命周期,避免手动分配和释放内存时可能出现的内存泄漏和悬挂指针等问题。在C++11标准中,引入了三种智能指针:unique_ptr、shared_ptr和weak_ptr。类型含义备注std::unique_ptr 独占资源......
  • C++STL进阶:pb_ds库
    Windows,64bitG++(ISOc20)stack=268435456开启O2优化万能头文件CodeForces在\(\ttC^{20(64)}_{++}\)版本下无法使用bits;如果需要使用priority_queue则无法使用using(会和std撞名字)。#include<bits/extc.h>usingnamespace__gnu_pbds;优先队列(不常用)概述......
  • C++的异常类型与多级catch匹配
    try-catch的用法:try{//可能抛出异常的语句}catch(exceptionTypevariable){//处理异常的语句}我们还遗留下一个问题,就是catch关键字后边的exceptionTypevariable,这节就来详细分析一下。exceptionType是异常类型,它指明了当前的catch可以处理什么类型的异常;varia......
  • C++ 学习笔记、01 | 开发简单职工管理系统遇到的一些问题
    记录开发简单职工管理系统遇到的一些问题,黑马教程https://www.bilibili.com/video/BV1et411b73ZP147~P166头文件与源文件头文件只声明,源文件来实现(本质上是类内声明类外实现)源文件需要引用特定的头文件ifndefOOPFINAL_WORKER_H#defineOOPFINAL_WORKER_H#include<......