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

  • 相关阅读:
    Redis 5.0 redis-cli --cluster
    Redis使用redis-trib.rb创建带密码的集群问题总结
    Docker实战之Redis-Cluster集群
    kafka作为流式处理的上一层,为什么吞吐量那么大?
    LAMP 实现全过程及wordpress的搭建
    mysql
    Mysql读写分离方案-MySQL Proxy环境部署记录
    Centos7.5部署MySQL5.7基于GTID主从复制+并行复制+半同步复制+读写分离(ProxySQL)
    iptables
    Nginx+Keepalived高可用集群
  • 原文地址:https://www.cnblogs.com/cplinux/p/5616441.html
Copyright © 2020-2023  润新知