zoukankan      html  css  js  c++  java
  • c++之拷贝构造函数调用时机

    test1:

     1 #include<iostream>
     2 using namespace std;
     3 class Copy_construction {
     4 public:
     5     Copy_construction(int a = 0)
     6     {
     7         this->a = a;
     8         cout << "这是有默认参数的构造函数!
    ";
     9     }
    10     Copy_construction(const Copy_construction &obj)
    11     {
    12         cout << "这是拷贝构造函数!
    ";
    13         a = obj.a;
    14     }
    15     ~Copy_construction()
    16     {
    17         cout << "一个对象被析构了!
    ";
    18     }
    19 private:
    20     int a;
    21 };
    22 void fuc(Copy_construction t)
    23 {
    24     cout << "fuc函数!
    ";
    25 }
    26 void play_empty(void)
    27 {
    28     Copy_construction t1;//调用有默认实参的构造函数
    29     Copy_construction t2 = t1;//调用拷贝构造函数
    30     Copy_construction t3(t2);//调用拷贝构造函数
    31     cout << "_________________
    ";
    32     fuc(t3);//实参初始化形参,调用拷贝构造函数
    33 }
    34 int main()
    35 {
    36     play_empty();
    37 
    38     cout << "hello world!
    ";
    39     return 0;
    40 }
    View Code

    运行结果

     test2:

    修改fuc函数为引用或者指针类型。

     1 void fuc(Copy_construction *t)
     2 {
     3     cout << "fuc函数!
    ";
     4 }
     5 
     6 
     7 void fuc(Copy_construction &t)
     8 {
     9     cout << "fuc函数!
    ";
    10 }
    11 
    12 /*****引用或者指针类型调用时不会调用拷贝构造函数****/

    test3:

    匿名对象的出现:

     1 #include<iostream>
     2 using namespace std;
     3 class Copy_construction {
     4 public:
     5     Copy_construction(int a = 0)
     6     {
     7         this->a = a;
     8         cout << "这是有默认参数的构造函数!
    ";
     9     }
    10     Copy_construction(const Copy_construction &obj)
    11     {
    12         cout << "这是拷贝构造函数!
    ";
    13         a = obj.a;
    14     }
    15     ~Copy_construction()
    16     {
    17         cout << "一个对象被析构了!
    ";
    18     }
    19 private:
    20     int a;
    21 };
    22 Copy_construction fuc(void)
    23 {
    24     cout << "fuc函数!
    ";
    25     Copy_construction A;
    26     return A;//调用拷贝构造函数,生成匿名对象
    27 }//运行到该处,先析构对象A,匿名对象是否析构要看怎么去接
    28 //如下所示直接调用fuc()则此时匿名对象会被立即析构
    29 void play_empty(void)
    30 {
    31     fuc();
    32 }
    33 int main()
    34 {
    35     play_empty();
    36 
    37     cout << "hello world!
    ";
    38     return 0;
    39 }

    如果直接显示调用构造函数,要看怎么去接这个函数, Copy_construction(1);调用之后马上执行析构匿名对象 Copy_construction  T= Copy_construction(1);不会马上析构还会转正

    test4:

    修改fuc函数的返回类型为引用或者指针:

     1 Copy_construction *fuc(void)
     2 {
     3     cout << "fuc函数!
    ";
     4     Copy_construction A;
     5     return &A;
     6 }
     7 
     8 Copy_construction &fuc(void)
     9 {
    10     cout << "fuc函数!
    ";
    11     Copy_construction A;
    12     return A;
    13 }
    14 
    15 
    16 /********返回类型为指针或者引用不会调用拷贝构造函数*********/

    test5:

    改变接匿名对象的方式:

     1 #include<iostream>
     2 using namespace std;
     3 class Copy_construction {
     4 public:
     5     Copy_construction(int a = 0)
     6     {
     7         this->a = a;
     8         cout << "这是有默认参数的构造函数!
    ";
     9     }
    10     Copy_construction(const Copy_construction &obj)
    11     {
    12         cout << "这是拷贝构造函数!
    ";
    13         a = obj.a;
    14     }
    15     ~Copy_construction()
    16     {
    17         cout << "一个对象被析构了!
    ";
    18     }
    19 private:
    20     int a;
    21 };
    22 Copy_construction fuc(void)
    23 {
    24     cout << "fuc函数!
    ";
    25     Copy_construction A;
    26     return A;//调用拷贝构造函数,产生匿名对象
    27 }//析构对象A,根据下面代码的接匿名对象的方式,
    28 //此时匿名对象不仅不会马上析构,还会转正成为对象B
    29 //从c++设计哲学上来说,这也是提高效率的一种方式,这样的设计是合理的,因为你想创建对象B,我就不用再新开辟内存了,直接用之前的匿名对象代替
    30 void play_empty(void)
    31 {
    32     Copy_construction B=fuc();//这里不会调用拷贝构造函数,匿名对象直接转正了
    33     cout << "匿名对象转正!
    ";
    34 }
    35 int main()
    36 {
    37     play_empty();
    38 
    39     cout << "hello world!
    ";
    40     return 0;
    41 }

    test6:

    再改变接匿名对象的方式,重写play_empty()函数:

    void play_empty(void)
    {
        Copy_construction B;
        B= fuc();
        cout << "匿名对象不会转正!
    ";
    }
    
    
    //如上所示代码,此时对象B会开辟内存,在用返回的匿名对象赋值给B,将会在赋值完成之后立即析构匿名对象,这个时候匿名对象不会转正。

    summary:以下情况会调用拷贝构造函数

    1.直接初始化和拷贝初始化时

    2.将一个对象作为实参传递给一个非引用或非指针类型的形参时

    3.从一个返回类型为非引用或非指针的函数返回一个对象时

    4.用花括号列表初始化一个数组的元素或者一个聚合类(很少使用)中的成员时。

  • 相关阅读:
    day3 数据类型
    子查询
    mysql综合练习题
    day5 练习
    月末总结
    Iconfont-阿里巴巴矢量图标库
    vue简介
    Redis简介和数据结构
    浏览器初始化css
    vue脚手架搭建项目初始化
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/6408275.html
Copyright © 2011-2022 走看看