c++匿名函数、普通函数、拷贝构造函数的一些研究

被c++的复杂坑了一把。。

以下为初学者的一些见解吧

首先贴上实验代码:

#include <iostream>
using namespace std;

class Test{

public:
    static int c;//用于计数对象
    int id;//使用id标识对象

    Test(const Test &a){//拷贝构造函数
        id = c++;
        cout << "This is copy constructor :" << a.id<< endl;
    }
    Test(){//空参构造函数
        id = c++;
        cout << "This is null constructor." << endl;
    }
    ~Test(){//析构函数
        cout << "This is destory:" << id << endl;
    }
    Test& operator =(const Test& t){//=运算符重载
      id = c++;
      cout << "= :" << t.id << endl;
      return *this;
    }
    void print(){cout  << "print:" << id << endl;}
};
int Test::c = 1;
Test Get(Test a){ 
    cout << "This is Get()\n";    
    return a;
}
int main(){    
    cout << "Start.\n";    
    
    Test t1 = Test(Test());   
    t1.print();   
    
    Get(t1);
    
    Test t2 = Get(t1);
    t2.print();
    
    t1 = t2; 
    t1.print(); 
    cout << "End.\n";
}
/*输出:
Start.
This is null constructor.
print:1
This is copy constructor :1
This is Get()
This is copy constructor :2
This is destory:3
This is destory:2
This is copy constructor :1
This is Get()
This is copy constructor :4
This is destory:4
print:5
= :5
print:6
End.
This is destory:5
This is destory:6


Process returned 0 (0x0)   execution time : 0.117 s
Press any key to continue.
*/

下面一步一步来解析,看完大概就能理解了吧:)

/一

 cout << "Start.\n";
 Test t1 = Test(Test());
 t1.print();

这里的输出结果是:

Start.
This is null constructor.
print:1

这里看起来像是用一个Test()匿名对象“拷贝构造”了一个匿名对象,然后初始化了t1,实际情况是只创建了一个对象(t1的ID是1,而不是其他),说明其中进行了一次构造,并没有调用拷贝构造。并且匿名对象并没有进行析构,说明是只构建了一个匿名对象并且该匿名对象直接“变”成了t1。

/二

Test Get(Test a){
    cout << "This is Get()\n";
    return a;
}
Get(t1);
这里输出结果是:
This is copy constructor :1
This is Get()
This is copy constructor :2
This is destory:3
This is destory:2
可以看出,传递进Get函数时使用了一次拷贝构造,拷贝了对象(id=1)(即为t1)给对象(id=2)(即为函数的形参),然后执行Get(),Get的返回值被传递进了一个随机的未知空间并通过拷贝构造创建了对象(id=3)(由对象id=2复制所得),之后函数的形参(id=2)以及未知的对象(id=3)被析构。

///三

 Test t2 = Get(t1);
 t2.print();

这里输出结果是:

This is copy constructor :1
This is Get()
This is copy constructor :4
This is destory:4
print:5

Get()执行和二类似,但是在析构的时候只析构了函数的形参(id=4),在实验二中的Get()会产生的未知的对象没有被析构,初始化的t2的id=5,并且在Get结束阶段拷贝构造函数只执行了一次且没有执行赋值函数,说明Get()结束阶段生成的那个未知对象是通过拷贝构造函数初始化的匿名对象, 此时这个对象id=5,将t2进行了初始化。

//四

  t1 = t2;
  t1.print();

  cout << "End.\n";

输出结果:

= :5
print:6
End.
This is destory:5
This is destory:6

这里将t2(id=5),通过赋值函数赋值给了t1,t1的id更新为6

随后将程序结束,将t1,t2进行了析构。


结论:

1.普通函数的形参(通过非引用传递)是通过拷贝构造函数创建的,并在函数结束时被析构

2.普通函数的返回值是通过形参拷贝构造了一个匿名函数(只考虑此文章中情况)

3.多个匿名对象空参初始化的嵌套实际只会生成一个匿名对象。

4.通过匿名对象的初始化并不会通过拷贝构造或者赋值函数

5.通过匿名对象的初始化实际上是将要初始化的对象指向了匿名函数所在的内存空间



ps:我只是初学者,可能有错,理解不到位,求大佬订正,勿喷

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值