变量初始化有三种方式:
方式 example
-------------------------------------------------
1.调用default ctor T t;
2.调用对应参数类型的ctor T t(parameter);
3.调用copy ctor T t = u;
值得注意的是在3时,虽然从表面上看有个=号,但不能以为就会用到assignment operator,不要被表面现象蒙蔽,这只是从c语法中沿用下来的。
另外,当u是T类型的对象时,T t = u; 相当于 T t(u); ;
但若u为其它类型对象时,它就相当于 T t(T(u)),先将u转化为一个临时的T对象,然后再调用copy ctor构造对象。有些编译器会优化掉这个临时对象,方法就是直接调用u的类型构造函数。vc7和bcc32都会进行这项优化处理。
[疑惑]但Exceptional C++说:如果这样优化,拷贝构造函数也是必须的。但我实验发现:没有必要有copy ctor,why?
所以,最好用2来代替3,而且2还有一个优势就时接受多个参数,3只能接受1个参数。
[experiment]
#include <iostream>
using namespace std;
class T {
public:
T()
{
id_ = ++count_;
cout << "T #" << id_ << " default ctor, ";
printCount();
}
T(int)
{
id_ = ++count_;
cout << "T #" << id_ << " T(int), ";
printCount();
}
T(const T& other)
{
id_ = ++count_;
cout << "T #" << id_ << " copy ctor from #" << other.id_ << ", ";
printCount();
}
~T()
{
--count_;
cout << "T #" << id_ << " destroyed, ";
printCount();
}
T& operator=(const T& rhs)
{
cout << "T #" << id_ << " assignment op from #" << rhs.id_ << endl;
return *this;
}
private:
void printCount() { cout << count_ << " instances exist" << endl; }
static int count_;
int id_;
};
int T::count_ = 0;
int main()
{
cout << "[1]------------------------/n";
T t1; // call default ctor
//T red_herring1(); // function declaration
cout << "[2]------------------------/n";
T t2(1); // call direct ctor
T t3(t1); // call copy ctor
//T red_herring2(T); // function declaration
cout << "[3]------------------------/n";
T t4 = 1; // call direct ctor
T t5 = t1; // call copy ctor
cout << "------- game over! --------/n";
}
[output]
[1]------------------------
T #1 default ctor, 1 instances exi
[2]------------------------
T #2 T(int), 2 instances exist
T #3 copy ctor from #1, 3 instance
[3]------------------------
T #4 T(int), 4 instances exist
------- game over! --------
T #4 destroyed, 3 instances exist
T #3 destroyed, 2 instances exist
T #2 destroyed, 1 instances exist
T #1 destroyed, 0 instances exist
[分析]
对象t4被编译器优化,直接调用了T::T(int),而不是先调用T::T(int)转化为temp,再用copy ctor构造
[Reference]
Exceptional C++ Item 42 Variable Initialization-Or is it?