类和对象(7)—— 拷贝构造函数应用场景

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

using namespace std;

class Test
{
public:
    //显示的无参数的构造函数
    Test()
    {
        cout << "Test()..." << endl;
        m_x = 0;
        m_y = 0;
    }
    //显式地有参数的构造函数
    Test(int x, int y)
    {
        cout << "Test(int x, int y)..." << endl;
        m_x = x;
        m_y = y;
    }

    //显式地拷贝构造函数
    Test(const Test &another)
    {
        cout << "Test(const Test &)..." << endl;
        m_x = another.m_x;
        m_y = another.m_y;
    }
    void printT()
    {
        cout << "x=" << m_x << ",y=" << m_y << endl;
    }
    
    //显示的拷贝析构函数
    ~Test()
    {
        cout << "~Test()..." << endl;
    }

    //赋值操作符
    void operator=(const Test &another)
    {
        cout << "operator=(const Test &)..." << endl;
        m_x = another.m_x;
        m_y = another.m_y;
    }

private:
    int m_x;
    int m_y;

};

//场景一
//析构函数调用的顺序,跟构造相反,谁先构造,谁后析构
void test1()
{
    cout << "test1 begin..." << endl;
    Test t1(10, 20);
    Test t2(t1);//等价于Test t2=t1;
    cout << "test1 end..." << endl;
}

//场景二
void test2()
{
    cout << "test2 begin..." << endl;
    Test t1(10, 20);
    Test t2;//等价于Test t2=t1;
    t2 = t1;
    cout << "test2 end..." << endl;
}

//场景三
void func1(Test t)//Test t = t1;实际上是Test t的拷贝构造函数
{
    cout << "func1 begin..." << endl;
    t.printT();
    cout << "func1 end..." << endl;
}

void test3()
{
    cout << "test3 begin..." << endl;
    Test t1(10, 20);
    func1(t1);
    cout << "test3 end..." << endl;
}

Test func2()
{
    cout << "func2 begin..." << endl;
    Test temp(10, 20);
    temp.printT();
    cout << "func2 end..." << endl;

    return temp;
}//会产生一个匿名的对象 = temp  匿名对象.拷贝构造(temp)

 //场景四
void test4()
{
    cout << "test4 begin..." << endl;
    Test t1(10, 20);
    func2();//返回一个匿名对象。
            //当一个函数返回匿名对象的时候,函数外部没有任何变量去接受它,
            //这个匿名对象将不会再被使用(即找不到),编译器会直接将这个匿名对象回收掉,
            //而不是等待整个函数执行完毕再回收。
    //匿名对象此时就被回收。
    cout << "test4 end..." << endl;
}

//场景五
void test5()
{
    cout << "test5 begin..." << endl;
    Test t1 = func2();//并不会触发t1拷贝,而是将匿名对象转正t1,
                      //将这个匿名对象 起了名字就叫t1。
    cout << "test5 end..." << endl;
}

//场景六
void test6()
{
    cout << "test6 begin..." << endl;
    Test t1;//
    t1 = func2();

    t1.printT();
    cout << "test6 end..." << endl;
}
int main(void)
{
    test1();
    cout << "-------------------" << endl;

    test2();
    cout << "-------------------" << endl;

    test3();
    cout << "-------------------" << endl;

    test4();
    cout << "-------------------" << endl;

    test5();
    cout << "-------------------" << endl;

    test6();

    return 0;
}

屏幕输出:

test1 begin...
Test(int x, int y)...
Test(const Test &)...
test1 end...
~Test()...
~Test()...
-------------------
test2 begin...
Test(int x, int y)...
Test()...
operator=(const Test &)...
test2 end...
~Test()...
~Test()...
-------------------
test3 begin...
Test(int x, int y)...
Test(const Test &)...
func1 begin...
x=10,y=20
func1 end...
~Test()...
test3 end...
~Test()...
-------------------
test4 begin...
Test(int x, int y)...
func2 begin...
Test(int x, int y)...
x=10,y=20
func2 end...
Test(const Test &)...
~Test()...
~Test()...
test4 end...
~Test()...
-------------------
test5 begin...
func2 begin...
Test(int x, int y)...
x=10,y=20
func2 end...
Test(const Test &)...
~Test()...
test5 end...
~Test()...
-------------------
test6 begin...
Test()...
func2 begin...
Test(int x, int y)...
x=10,y=20
func2 end...
Test(const Test &)...
~Test()...//析构局部元素temp
operator=(const Test &)...
~Test()...//析构匿名对象
x=10,y=20
test6 end...
~Test()...

结论:

结论一:func2()函数 返回一个元素。

  函数的返回值是一个元素(复杂类型的),返回的是一个新的匿名对象(所以会调用匿名对象类的拷贝构造函数);

结论二:有关 匿名函对象的去和留

  如果用匿名对象 初始化 另外一个同类型的对象,匿名对象转成有名对象;

  如果用匿名对象 赋值给 另一个同类型的对象,匿名对象被析构。

原文地址:https://www.cnblogs.com/yuehouse/p/9795287.html