• Effective Modern C++ ——条款7 在创建对象时注意区分()和{}


    杂项

    在本条款的开头书中提到了两个细节性问题:

    1、类中成员初始化的时候不能使用小括号。
    如:

    class A {
     int a(0);//错误
    };
    

    2、对于原子性类别的对象初始化的时候不能使用=
    如:

    std::atomic<int> a = 0;//错误
    

    大括号初始化的特性(以下都是使用{}初始化对象时具备的特性):

    1、禁止窄式类别转换
    double x,y,z;
    int sum(x+y+z);//错误 double之和可能无法用int 表达
    
    2、能避免令人苦恼的解析语法

    C++规定:任何能解释为声明的语句都要解释为声明。

    MyClass w();//你只是想新建一个对象,但是编译器可能会解释为你在声明一个函数
    
    3、std::initializer_list型别对于编译器有着致命吸引力。

    在你的构造函数中,如果出现形参型别为std::initializer_list,编译器会想尽一切办法调用这个构造函数初始化对象。

    class A {
    public:
        A(int i, double b){};
        A(std::initializer_list<bool> i){};
    };
    
    int main() {
        A a{10, 6.0};//错误,无法从double转换成bool(窄化转换)
    }
    

    下面这种情况就不用多说了:

    class A {
    public:
        A(int i, bool b){};
        A(std::initializer_list<double> i){};
    };
    
    int main() {
        A a{10, 6.0};//编译器很开心的会调用第二个构造函数
    }
    
    

    所以除非你不给他任何机会:

    class A {
    public:
        A(int i, double b){};
        A(std::initializer_list<string> i){};
    };
    
    int main() {
        A a{10, 6.0};//编译器没办法了,只能调用第一个了。
    }
    
    

    还有一种例外的情况就是在你既支持默认构造函数,又支持带有std::initializer_list类型的构造函数的时候;

    使用空大括号构造对象时,会调用默认的构造函数,意义是没有实参,除非你用两个大括号像这样:Myclass a{{}}

    关于大括号和小括号区别

    在vector中有例子佐证:

    std::vector<int> v1(10, 20)//小括号,老老实实创建了一个vector 含有10个元素,元素值都为20;
    
    std::vector<int> v2{10,20}//大括号,调用带有std::initializer_list形参的构造函数,创建一个含有两个元素的vector 元素值为10,20
    
  • 相关阅读:
    iOS常用第三方库之Masonry
    iOS超全面试题,面试前看一看,不错
    自学安卓练习作品单词APP(1)-安卓的hello word与有道字典防爬虫破解
    shrio的rememberMe不起作用
    上传组件uploadify在spring中返回406 / Not Acceptable 问题解决
    由max_allowed_packet引发的mysql攻防大战
    又到毕业季你为什么没有工作
    mavan下scala编译中文乱码的问题.以及内存溢出问题解决
    @RestController失效
    BeanInstantiationException: Failed to instantiate [java.time.LocalDateTime]
  • 原文地址:https://www.cnblogs.com/Smarc/p/13593830.html
Copyright © 2020-2023  润新知