构造函数

  从值e构造出一个类型T的值可以用函数记法T(e)表述。例如,

    void f(double d)
    {
        int i = int(d);            // 截断d
        complex z = complex(d);    // 从d做出一个complex
        // ...
    }

这种T(e)结构有时被称做函数风格的强制。不幸的是,对于内部类型T而言,T(e)等价于(T)e,这也意味着T(e)对于许多内部类型是不安全的。对于算术类型,值的转换可以出现截断,甚至从较长的整数类型到较短(如从long到char)的显式转换也可能导致不可移植的依赖于具体实现的行为。我将只在一个值的构造有良好定义的地方使用这种记法,即用算术类型之间的缩窄转换(C.6节),从整数到枚举的转换(4.8节)和用户定义类型的对象构造(2.5.2节、10.2.3节)。

  指针转换不能直接采用T(e)的记法形式表示。例如,char*(2)是一个语法错误。让构造函数的记法回避这样的一类危险转换是件很好的事情。但不幸的是,这种保护却会被指针使用typedef产生的名字(4.9.7节)所打破。

  构造函数记法T()用于描述类型T的默认值。例如

    void f(double d)
    {
        int j = int();            // 默认的int值
        complex z = complex();    // 默认的complex值
        // ...
    }

对于内部类型而言,这样显式地使用构造函数,得到的是将0转换到该类型所得到的值(4.9.5节)。这样。int()也就是写0的另一种方式。对于用户定义类型T,如果存在这种函数的话,T()由T的默认构函数定义(10.4.2节)。

  对于内部类型也能使用构造函数记法,这一点在写模板的时候就特别重要。在这种情况下,程序员无法知道一个模板参数是内部类型还是用户定义类型(16.3.4节、17.4.1.2节)。

🔚