拷贝构造函数

我们先看一个普通的构造函数的使用

class Test
{
private:
    /* data */
public:
    Test(int a);
    ~Test();
    int A;
};

Test::Test(int a)
{
    A = a;
}

Test::~Test()
{
}


int main()
{
    Test test(1);
    cout<<test.A<<endl;

}

我们定义了一个类 Test 并用了类名定义了一个构造函数,用来传入成员变量A的值。

这是一个正常的构造函数的用法。

那么拷贝构造函数什么时候用呢?

当我想用一个对象去初始化另一个对象的时候。

Test A;
Test A(B);

就需要用到拷贝构造函数,我们看一下怎么写

class Test
{
private:
    /* data */
public:
    Test(int a);
    Test(const Test &q);
    ~Test();
    int A;
};

Test::Test(int a)
{
    A = a;
}

Test::Test(const Test &q)
{
    A = q.A + 1;
}

Test::~Test()
{
}


int main()
{
    Test test(1);
    Test test2(test);
    Test test3 = test;
    cout<<test.A<<endl;
    cout<<test2.A<<endl;
    cout<<test3.A<<endl;
}

输出结果

1
2
2

代码中标红的部分,就是拷贝构造函数,和他的调用方法。为了区分 用拷贝构造函数赋值的对象,所以我给 A 加了 1 .

假设现在我有一个普通函数调用了刚创建的类,我们看一下运行结果

class Test
{
private:
    /* data */
public:
    Test(int a);
    Test(class Test &q);
    ~Test();
    int A;
};

Test::Test(int a)
{
    A = a;
}

Test::Test(class Test &q)
{
    A = q.A + 1;
}

Test::~Test()
{
}

void get(Test p)
{
    cout<<"the A int get() is : "<<p.A<<endl;
}


int main()
{
    Test test(1);
    Test test2(test);
    Test test3 = test;
    cout<<test.A<<endl;
    cout<<test2.A<<endl;
    cout<<test3.A<<endl;
    get(test2);
}

运行结果:

1
2
2
the A int get() is : 3

证明我们在调用 get函数,传参的时候  Test p 又重新调用了一次拷贝构造函数,所以输出的值是3

如果我要在构造函数中调用构造函数,会是什么样的结果呢?
看这样的一个例子

class Test
{
private:
    /* data */
public:
    Test(int a,int b);
    Test(int a,int b,int c);
    ~Test();
    int A,B,C;
};

Test::Test(int a,int b)
{
    A = a;
    B = b;
    Test(a,b,100);
}

Test::Test(int a,int b,int c)
{
    A = a;
    B = b;
    C = c;
}

Test::~Test()
{
/*  cout<<"---------"<<endl;
    cout<<A<<endl;
    cout<<B<<endl;
    cout<<C<<endl;
    cout<<"---------"<<endl;
*/
}
int main(void) { Test test(1,1); cout<<test.A<<endl; cout<<test.B<<endl; cout<<test.C<<endl; }

重载了构造函数并且在2个参数的构造函数中调用了3个参数的构造函数。结果会是 a = 1 b = 1 c = 100吗

输出结果如下:

1
1
30

第三个数字并非我们想要的100

我们在析构函数中加上打印,看一下输出结果

---------
1
1
100
---------

1
1
30

---------
1
1
30
---------

中间红色部分是主函数中的打印结果 1 1 30

前后两次是析构函数打印出来的,证明一开始c = 100 确实真的传入了对象当中,但是被析构函数释放掉了

也就是说在执行2个参数的构造函数中,执行了一次析构函数。

我们尽量避免不断的多次调用构造函数

原文地址:https://www.cnblogs.com/qifeng1024/p/12636716.html