封装-构造和析构2

没有任何返回值。
初始化列表, 效率更高,用不了this指针
一是使用初始化列表,二是在构造函数体内进行赋值操作。使用初始化列表主要是基于性能问题,对于内置类型,如int, float等,使用初始化类表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表,为什么呢?由上面的测试可知,使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。同样看上面的例子,我们使用初始化列表来实现Test2的构造函数
【封装-构造和析构2】struct Test2
{

Test1 test1 ; Test2(Test1 &t1):test1(t1){}

}
使用同样的调用代码,输出结果如下。
construct Test1 copy constructor for Test1

第一行输出对应 调用代码的第一行。第二行输出对应Test2的初始化列表,直接调用拷贝构造函数初始化test1,省去了调用默认构造函数的过程。所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表。
举例
lass X { public: int m_i; X(int value = https://www.it610.com/article/0) :m_i(value) { printf("this = %p", this); cout << "X(int)构造函数被调用" << endl; } X(const X &tmpv) { printf("this = %p", this); cout << "X拷贝构造函数被调用" << endl; } X& operator=(const X &tmpv) { printf("this = %p", this); cout << "X拷贝赋值运算符被调用" << endl; return *this; } ~X() { printf("this = %p", this); cout << "X析构函数被调用" << endl; } }; class Y{ public: X xobj; //类类型对象 Y(int tmpvalue) :xobj(1000)//这里构造了xobj,此处若没有使用初始化成员列表,耗费了一次构造函数调用的机会 // 编译器角度(没用初始化列表) //X xobj; //xobj.X::X(); // 编译器角度(用了初始化列表) //X xobj; //xobj.X::X(1000); { //xobj = 1000; //若不使用初始化列表。这里构造一个临时对象,把临时对象内容给了xobj,之后释放xobj //编译器视角 //x tmpobj; //(1)生成临时对象 //tmpobj.X::X(1000); //(2)临时对象调用构造函数 //xobj.X::operator=(tmpobj); //(3)调用拷贝赋值运算符 //tmpobj.X::~X(); //(4)调用析构函数 } };

    推荐阅读