• C++的explicit是什么?


    一、提要

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

    二、隐式转换是什么?

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

    1. #include
    2. using namespace std;
    3. class Point {
    4. public:
    5. int x, y;
    6. Point(int x = 0, int y = 0)
    7. : x(x), y(y) {}
    8. };
    9. void displayPoint(const Point& p)
    10. {
    11. std::cout << "(" << p.x << "," << p.y << ")" << std::endl;
    12. }
    13. int main()
    14. {
    15. displayPoint(1);
    16. Point p=30 ;
    17. displayPoint(p );
    18. }

     以上的隐式转化有两个:

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

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

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

    三、更灵活应用

    1. class CxString // 没有使用explicit关键字的类声明, 即默认为隐式声明
    2. {
    3. public:
    4. char *_pstr;
    5. int _size;
    6. CxString(int size)
    7. {
    8. _size = size; // string的预设大小
    9. _pstr = malloc(size + 1); // 分配string的内存
    10. memset(_pstr, 0, size + 1);
    11. }
    12. CxString(const char *p)
    13. {
    14. int size = strlen(p);
    15. _pstr = malloc(size + 1); // 分配string的内存
    16. strcpy(_pstr, p); // 复制字符串
    17. _size = strlen(_pstr);
    18. }
    19. // 析构函数这里不讨论, 省略...
    20. };

    因此:

     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内存指针的时候可能会报错, 完整的代码必须重载运算符"=", 并在其中处理内存释放  

    四、限定构造函数必须显式

    1. class Test1
    2. {
    3. public:
    4. Test1(int n)
    5. {
    6. num=n;
    7. }//普通构造函数
    8. private:
    9. int num;
    10. };
    11. class Test2
    12. {
    13. public:
    14. explicit Test2(int n)
    15. {
    16. num=n;
    17. }//explicit(显式)构造函数
    18. private:
    19. int num;
    20. };
    21. int main()
    22. {
    23. Test1 t1=12;//隐式调用其构造函数,成功
    24. Test2 t2=12;//编译错误,不能隐式调用其构造函数
    25. Test2 t2(12);//显式调用成功
    26. return 0;
    27. }

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

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

  • 相关阅读:
    塑造下一代教育的关键力量:AIGC在教育革命中的角色扮演
    2020上海智慧城市合作大会,零数科技受邀出席并入选优秀应用案例
    最新Next 14快速上手基础部分
    8/3 训练日志 (树状数组+区间覆盖+思维+01字典树)
    Spring Boot | Spring Boot 默认 “缓存管理“ 、Spring Boot “缓存注解“ 介绍
    数据挖掘与机器学习:循环结构
    c++day2---9.7
    excel怎么批量提取指定网站内容-免费指定网站提取导出excel软件
    HNUCM 您好中国
    图标、图片、矢量图注册,通过名称来配置icon可以提高性能
  • 原文地址:https://blog.csdn.net/gongdiwudu/article/details/125997902