C++中的拷贝构造、赋值构造函数

C++中的拷贝构造、赋值构造函数

C++中的拷贝构造,赋值构造的形式如下:

eg:

A (A &a) {
        this->x = a.x;
        this->y = a.y;
        cout << "这是一个拷贝构造函数" << endl;
    }
    A(const A &a)  {
        this->x = a.x;
        this->y = a.y;
        cout << "这是一个拷贝构造函数" << endl;
    }
    A &operator = (const A &a) {
        this->x = a.x;
        this->y = a.y;
        cout << "这是一个赋值构造函数" << endl;
    }

对象以值传递方式从函数返回时,若接受返回值的对象已经初始化过,则会调用赋值构造函数,且该对象还会调用析构函数,当对象中包含指针时,会使该指针失效,因此需要重载赋值构造函数,使用类似深拷贝或移动构造函数的方法赋值,才能避免指针失效。

拷贝构造测试

#include<bits/stdc++.h>
using namespace std;
class A {
public:
    int *x;
    int y;
    A();
    A (A &a) {
        this->x = a.x;
        this->y = a.y;
        cout << "这是一个拷贝构造函数" << endl;
    }
    A(const A &a)  {
        this->x = a.x;
        this->y = a.y;
        cout << "这是一个使用了const的拷贝构造函数" << endl;
    }
    A &operator = (const A &a) {
        this->x = a.x;
        this->y = a.y;
        cout << "这是一个赋值构造函数" << endl;
    }
    A (int t) {
        x = new int(0);
        y = t;
        printf("address: %x, point:%x, val: %d\n", this, x, y );
    }
    ~A() {
        printf("delete %x\n", this);
    }

};
void func(A ret) {
    printf ("传值:stack address: %x, point: %x, value: %d\n", &ret, ret.x, ret.y);
}
A get() {
    A ret(3);
    printf ("从函数返回时stack address: %x, point: %x, value: %d\n", &ret, ret.x, ret.y);
    return ret;
}
int main() {
    A a(1);
    A c = a;
    printf ("C的:global address: %x, point: %x, value: %d\n", &c, c.x, c.y);
    func(c);
    A d = get();
    printf ("D的:global address: %x, point: %x, value: %d\n", &d, d.x, d.y);

    return 0;
}

测试结果

address: 89fed0, point:fb1698, val: 1
这是一个拷贝构造函数
C的:global address: 89fed8, point: fb1698, value: 1
这是一个拷贝构造函数
传值:stack address: 89fee0, point: fb1698, value: 1
delete 89fee0
address: 89fee8, point:fb1798, val: 3
从函数返回时stack address: 89fee8, point: fb1798, value: 3
D的:global address: 89fee8, point: fb1798, value: 3
delete 89fee8
delete 89fed8
delete 89fed0

赋值构造测试

#include<bits/stdc++.h>
using namespace std;
class A {
public:
    int *x;
    int y;
    A() = default;
    // A (const A &a) {
    //     this->x = a.x;
    //     this->y = a.y;
    //     cout << "这是一个const赋值构造函数" << endl;

    // }
    A &operator = (const A &a) {
        this->x = a.x;
        this->y = a.y;
        cout << "这是一个赋值构造函数" << endl;
    }
    A (int t) {
        x = new int(0);
        y = t;
        printf("address: %x, point:%x, val: %d\n", this, x, y );
    }
    ~A() {
        printf("delete %x\n", this);
    }

};
void func(A ret) {
    printf ("传值:stack address: %x, point: %x, value: %d\n", &ret, ret.x, ret.y);
}
A f () {
    A ret (3);
    printf ("stack address: %x, point: %x, value: %d\n", &ret, ret.x, ret.y);
    return ret;
}
int main() {
    A c;
    c = f();
    printf ("global address: %x, point: %x, value: %d\n", &c, c.x, c.y);
    A a(1);
    A d = a;
    printf ("global address: %x, point: %x, value: %d\n", &d, d.x, d.y);

    return 0;
}

测试结果

address: 89fee8, point:f51788, val: 3
stack address: 89fee8, point: f51788, value: 3
这是一个赋值构造函数
delete 89fee8
global address: 89fed8, point: f51788, value: 3
address: 89fee0, point:f51698, val: 1
global address: 89fee8, point: f51698, value: 1
delete 89fee8
delete 89fee0
delete 89fed8

C++中拷贝赋值函数的形参能否进行值传递?

形参进行值传递:

A( A);

不能。如果是这种情况下,调用拷贝构造函数的时候,首先要将实参传递给形参,这个传递的时候又要调用拷贝构造函数。。如此循环,无法完成拷贝,栈也会满。(俗称套娃)

posted @ 2020-02-13 21:35  buerdepepeqi  阅读(531)  评论(0编辑  收藏  举报