构造函数constructor 与析构函数destructor(二)

(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这句话只是调用了运算符重载函数,所以这句话中的=号是赋值。

原文地址:https://www.cnblogs.com/cplinux/p/5616441.html