首页 > 编程语言 > 详细

C++——explicit

时间:2020-11-22 14:07:25      阅读:48      评论:0      收藏:0      [点我收藏+]

explicit主要是用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。类构造函数默认情况下声明为隐式的即implicit。

 

1、explicit 修饰构造函数时,可以防止隐式转换和复制初始化

class gxgExplicit  //没有关键字explicit的类
{
    public:
    int _size;
    gxgExplicit(int size)
    {
        _size = size;
    }
};

//下面是调用
   gxgExplicit gE1(24);     //这样是没有问题的
   gxgExplicit gE2 = 1;     //这样也是没有问题的
   gxgExplicit gE3;         //这样是不行的,没有默认构造函数
   gE1 = 2;                 //这样也是没有问题的
   gE2 = 3;                 //这样也是没有问题的
   gE2 = gE1;               //这样也是没有问题的

但是假如gxgExplicit修改为Stack,我们的_size代表的是堆栈的大小,那么调用的第二句就显得不伦不类,而且容易让人疑惑。这并不是可以让代码阅读者明白和接受的形式,虽然它是合法的(编译器可以通过编译)。这是因为编译器默认情况下有隐式转换的功能,你输入gE2 = 1就编译成同第一句相同的结果。所以,explicit就派上了用场。修改代码为:

class gxgExplicit
{
public:
    int _size;
    explicit gxgExplicit(int size)
    {
        size = size;
    }
};

//继续上面的调用:
gxgExplicit gE1(24);     //这样是没有问题的
gxgExplicit gE2 = 1;     //这样是不行的,关键字取消了隐式转换
gxgExplicit gE3;         //这样是不行的,没有默认构造函数
gE1 = 2;                 //这样是不行的,关键字取消了隐式转换
gE2 = 3;                 //这样是不行的,关键字取消了隐式转换
gE2 = gE1;               //这样是不行的,关键字取消了隐式转换,除非类实现操作符“=”的重载。

当构造函数参数超过两个时自动取消隐式转换。这是有没有关键字效果是一样的。那就是相当于有这个关键字。
但是另外一种情况例外:其中只有一个必须输入的参数,其余的为有默认值的参数。

class gxgExplicit
{
private:
   int _size;
   int _age;
public:
   explicit gxgExplicit(int age,int size = 0)
   {
      _age = age;
      _size = size;
   }
};
class gxgExplicit
{
private:
   int _size;
   int _age;
int _hight;
public:
   explicit gxgExplicit(int age,int size = 0)
   {
      _age = age;
      _size = size;
      _hight = hight;
   }
};

 

 

2、explicit 修饰转换函数时,可以防止隐式转换,但 按语境转换 除外

标准数据之间会进行  隐式类型安全转换。

技术分享图片

 

 

struct A
{
    A(int) { }
    operator bool() const { return true; }
};

struct B
{
    explicit B(int) {}
    explicit operator bool() const { return true; }
};

void doA(A a) {}

void doB(B b) {}

int main()
{
    A a1(1);        // OK:直接初始化
    A a2 = 1;        // OK:复制初始化
    A a3{ 1 };        // OK:直接列表初始化
    A a4 = { 1 };        // OK:复制列表初始化
    A a5 = (A)1;        // OK:允许 static_cast 的显式转换 
    doA(1);            // OK:允许从 int 到 A 的隐式转换
    if (a1);        // OK:使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
    bool a6(a1);        // OK:使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
    bool a7 = a1;        // OK:使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
    bool a8 = static_cast<bool>(a1);  // OK :static_cast 进行直接初始化

    B b1(1);        // OK:直接初始化
    B b2 = 1;        // 错误:被 explicit 修饰构造函数的对象不可以复制初始化
    B b3{ 1 };        // OK:直接列表初始化
    B b4 = { 1 };        // 错误:被 explicit 修饰构造函数的对象不可以复制列表初始化
    B b5 = (B)1;        // OK:允许 static_cast 的显式转换
    doB(1);            // 错误:被 explicit 修饰构造函数的对象不可以从 int 到 B 的隐式转换
    if (b1);        // OK:被 explicit 修饰转换函数 B::operator bool() 的对象可以从 B 到 bool 的按语境转换
    bool b6(b1);        // OK:被 explicit 修饰转换函数 B::operator bool() 的对象可以从 B 到 bool 的按语境转换
    bool b7 = b1;        // 错误:被 explicit 修饰转换函数 B::operator bool() 的对象不可以隐式转换
    bool b8 = static_cast<bool>(b1);  // OK:static_cast 进行直接初始化

    return 0;
}

 

 

参考:

https://www.cnblogs.com/QG-whz/p/4472566.html

https://www.jb51.net/article/41526.htm

https://www.cnblogs.com/hjxzjp/p/11768674.html

C++——explicit

原文:https://www.cnblogs.com/calla/p/13655027.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!