(1)转换构造函数
转换构造函数的定义:转换构造函数就是把普通的内置类型转换成类类型的构造函数,这种构造函数只有一个参数。只含有一个参数的构造函数,可以作为两种构造函数,一种是普通构造函数用于初始化对象,一种是转换构造函数
1 //test.h 2 #ifndef TEST_H 3 #define TEST_H 4 class Test{ 5 int m_i; 6 public: 7 Test(int i = 0);//转换构造函数,也是普通构造函数 8 ~Test(); 9 10 }; 11 #endif //TEST_H 12 13 14 15 //test.cpp 16 #include"Test.h" 17 #include<iostream> 18 using std::cout; 19 using std::endl; 20 21 22 Test::Test(int i) :m_i(i){ 23 cout << "Test(int i):" <<"m_i="<<m_i<< endl; 24 } 25 Test::~Test(){ 26 cout << "~Test()" << endl; 27 28 } 29 30 31 //demo.cpp 32 33 #include<iostream> 34 #include"Test.h" 35 int main(){ 36 Test t(12);//此时调用普通构造函数,初始化t 37 t = 15;//此时调用转换构造函数把15转换成类对象,生成临时对象 38 39 return 0; 40 41 }
在上面的t=15这段代码中,会生成临时对象,那么临时对象是什么时候释放的呢?
#ifndef TEST_H #define TEST_H class Test{ int m_i; public: Test(int i = 0); ~Test(); }; #endif //TEST_H #include"Test.h" #include<iostream> using std::cout; using std::endl; Test::Test(int i) :m_i(i){ cout << "Test(int i):" <<"m_i="<<m_i<< endl; } Test::~Test(){ cout << "~Test()" << endl; } #include<iostream> #include"Test.h" int main(){ Test t(12);//调用构造函数,执行Test(int i):m_i=12 t = 15;//生成临时对象,调用转换构造函数Test(int i):m_i=15,当把临时对象赋值给t后,里面调用了析构函数,把m_i值为15的临时对象释放掉
Test t2;//调用默认构造函数,Test(int):m_i=0; 然后调用析构函数把t和t2对象释放
return 0; }
类的构造函数只有一个参数是非常危险的,因为编译器可以使用这种构造函数把参数的类型隐式转换为类类型。所以有时候我们在构造函数的前面加一个关键字explicit,这样普通的内置类型就不能隐式的转换成类对象了。
赋值运算符和初始化的区别:
1 //在类里面加入如下的函数,对赋值运算的重载 2 const Test& Test::operator=(const Test& vt){ 3 m_i = vt.m_i; 4 return *this; 5 } 6 7 8 9 10 #include<iostream> 11 #include"Test.h" 12 int main(){ 13 Test t(12);//此时只会调用构造函数 14 t = 15;//会调用构造函数构造生成临时对象,临时对象向t赋值时,会调用=号的重载函数 15 16 Test t2=9;//此时只会调用构造函数,没有调用=号的重载函数 17 t2 = t;//调用=号重载,此时的=号是赋值运算符。 18 return 0; 19 20 }
根据设置断点实验,跟踪运算符重载函数和构造函数可以看到,t=15这句话是先调用构造函数,然后再调用运算符重载函数,说明是先生成临时变量,然后把临时变量赋值给t,Test t2=9这句话只调用了构造函数,所以这句话属于初始化,t2=t这句话只是调用了运算符重载函数,所以这句话中的=号是赋值。