不象C#,Java 等托管语言,在 C++ 中对变量的初始化问题很重要。比如,如果使用一个指针,没有初始化很容易成为 野指针 。例如:char *str; // 指针 str 的指向不为 NULL ,而是不确定的空间,很危险。
下面有四行代码,看看有什么区别。(T 代表某个类 )
T t;
T t();
T t(u);
T t = u;
在这里,想要说明三种不同的初始化之间的差别,即: 默认初始化 , 直接初始化 和 拷贝初始化 。
T t;
这个是默认初始化。声明了一个变量类型为T 的 t ,并通过 默认构造函数 T::T()来初始化。
T t(u);
假设u 是同种类型的变量,那么上面的这行代码就是 直接初始化。 这将调用函数T::T(u), 并用 u 的值来对变量 t 进行直接初始化。
T t();
这个是函数声明,不是初始化。其中函数名为t ,不带参数并返回一个 T 类型的对象。
T t = u;
上面这行是拷贝初始化。变量t 通常是调用 T 的 拷贝构造函数 来进行初始化。
注意:
拷贝初始化过程绝对不是赋值过程,因此在初始化过程中不会调用函数T::operator=() 。 = 号是从 C 语言中沿用过的一种语法,不代表赋值。
容易困惑的地方:
如果u 是 t 的对象,那么 T t = u; 与 T t(u) ,的含义是一样的。
如果u 是其他类型的对象,那么 T t = u; 相当于 T t(T(u)); 也就是将 u 变换成 T 的临时对象,然后调用拷贝构造函数将临时对象复制到 t 。
建议:
如果有可能的话,我们应该优先选择使用T t(u);
而不是 T t = u; 能够使用后者的地方,前者都可以胜任,反之不成立。比如有多个参数是只能用前者。
本文是Exceptional C++中文版条款42的读书笔记