栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++的explicit是什么?

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++的explicit是什么?

一、提要

        面向对象规则中,在对象生成的时候,存在隐式和显式两个方式。隐式调用构造函数,使得调用很灵活。但是,有些情况必须显式,此时可以选择“必须显式”的模式。explicit就是限定构造函数,使其只能显式调用,不能隐式转换的关键词。

二、隐式转换是什么?

        看一下这种隐式类型转换是怎么发生的吧.

#include 
using namespace std;

class Point {
public:
    int x, y;
    Point(int x = 0, int y = 0)
        : x(x), y(y) {}
};

void displayPoint(const Point& p)
{
    std::cout << "(" << p.x << "," << p.y << ")" << std::endl;
}

int main()
{
    displayPoint(1);
    Point p=30 ;
    displayPoint(p );
}

 以上的隐式转化有两个:

1) displayPoint(1);   此处的“1”是这样得到的:

                    从" const Point& "知道,此处的“1”是调用Point(1)获得。

2) Point p=30 ;此处的p先调用Point(3)完成。

三、更灵活应用
class CxString  // 没有使用explicit关键字的类声明, 即默认为隐式声明  
{  
public:  
    char *_pstr;  
    int _size;  
    CxString(int size)  
    {  
        _size = size;                // string的预设大小  
        _pstr = malloc(size + 1);    // 分配string的内存  
        memset(_pstr, 0, size + 1);  
    }  
    CxString(const char *p)  
    {  
        int size = strlen(p);  
        _pstr = malloc(size + 1);    // 分配string的内存  
        strcpy(_pstr, p);            // 复制字符串  
        _size = strlen(_pstr);  
    }  
    // 析构函数这里不讨论, 省略...  
}; 

因此:

 CxString string1(24);     // 这样是OK的, 为CxString预分配24字节的大小的内存  
    CxString string2 = 10;    // 这样是OK的, 为CxString预分配10字节的大小的内存  
    CxString string3;         // 这样是不行的, 因为没有默认构造函数, 错误为: “CxString”: 没有合适的默认构造函数可用  
    CxString string4("aaaa"); // 这样是OK的  
    CxString string5 = "bbb"; // 这样也是OK的, 调用的是CxString(const char *p)  
    CxString string6 = 'c';   // 这样也是OK的, 其实调用的是CxString(int size), 且size等于'c'的ascii码  
    string1 = 2;              // 这样也是OK的, 为CxString预分配2字节的大小的内存  
    string2 = 3;              // 这样也是OK的, 为CxString预分配3字节的大小的内存  
    string3 = string1;        // 这样也是OK的, 至少编译是没问题的, 但是如果析构函数里用free释放_pstr内存指针的时候可能会报错, 完整的代码必须重载运算符"=", 并在其中处理内存释放  

四、限定构造函数必须显式
class Test1 
{ 
public:
Test1(int n)
{
num=n;
}//普通构造函数
private:
int num;
};
class Test2
{ 
public:
explicit Test2(int n) 
{ 
num=n; 
}//explicit(显式)构造函数
private:
int num;
};
int main()
{
Test1 t1=12;//隐式调用其构造函数,成功
Test2 t2=12;//编译错误,不能隐式调用其构造函数
Test2 t2(12);//显式调用成功
return 0;
} 

        Test1的构造函数带一个int型的参数,代码23行会隐式转换成调用Test1的这个构造函数。而Test2的构造函数被声明为explicit(显式),这表示不能通过隐式转换来调用这个构造函数,因此代码24行会出现编译错误。

        普通构造函数能够被隐式调用。而explicit构造函数只能被显式调用。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1026315.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号