C++之拷贝构造函数

当类对象作为形参传入函数

C++中拷贝构造函数会有几种情况被调用,第一种是当对象作为形参传入函数时,这个时候系统会调用拷贝构造函数。

#include <iostream>
#include <cstring>

using namespace std;

class CopyStructureFunction {
public:
    CopyStructureFunction(int width) : w(width) {
        cout << "structure function is created" << endl;
    }

    CopyStructureFunction(const CopyStructureFunction &obj) {
        w = obj.w;
        cout << "copy structure function is created" << endl;
    }

    ~CopyStructureFunction() {
        printf("析构函数已被调用\n");
    };

    int get_width();


private:
    int w;
};

int CopyStructureFunction::get_width() {
    return w;
}
//隐式调用拷贝构造函数
void get_func(CopyStructureFunction cs);


int main() {
    system("chcp 65001");
    int width = 10;
    CopyStructureFunction cs(width);
    //当对象传入函数时,拷贝构造函数被调用
    get_func(cs);
    int w;
    int w_2;
    w = cs.get_width();
    cout << "普通构造函数的get_width():" << w << endl;
    //显示调用拷贝构造函数
    CopyStructureFunction cs_2 = cs;
    w_2 = cs_2.get_width();
    cout << "拷贝构造函数的get_width():" << w_2 << endl;

    return 0;
}

void get_func(CopyStructureFunction cs) {
    cout << "将类对象传入函数" << endl;
}
输出:
Active code page: 65001
structure function is created
copy structure function is created
将类对象传入函数
析构函数已被调用
普通构造函数的get_width():10
copy structure function is created
拷贝构造函数的get_width():10
析构函数已被调用
析构函数已被调用

get_func()就是一个典型的类对象传入函数调用拷贝函数的例子,这个时候C++会先创建一个临时变量,然后调用拷贝构造函数把对象cs的成员变量的值传给临时变量,等get_func()执行完之后,析构掉临时变量这个对象。
拷贝构造函数被调用的几个原则:
拷贝构造函数只有单个形参,这个形参常用const&修饰,是对该类类型的引用,当定义一个新对象并用同类的对象对其初始化(赋值)时,将显示调用拷贝构造函数,若将对象以值作为参数传入函数或将对象作为返回值返回,那么就会隐式调用拷贝构造函数。
若没有定义拷贝构造函数,则程序会自动创建拷贝构造函数。
必须要创建拷贝构造函数的情况:
只包含类类型成员或内置类型(但不是指针类型)成员的类,无须显式地定义拷贝构造函数也可以拷贝;有的类有一个数据成员是指针,或者是有成员表示在构造函数中分配的其他资源,这两种情况下都必须定义拷贝构造函数。
总结:
什么情况使用拷贝构造函数:
类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
(1)一个对象以值传递的方式传入函数体
(2)一个对象以值传递的方式从函数返回
(3)一个对象需要通过另外一个对象进行初始化。

当对象引用传入函数时,不会调用拷贝构造函数

#include <iostream>

using namespace std;

class Test {
public:
    int *ptr;

    //structure func
    Test(int x) {
        cout << "调用普通构造函数" << endl;
        ptr = new int;
        *ptr = x;
    }

    //copy structure func
    Test(const Test &t) {
        cout << "调用拷贝构造函数" << endl;
        ptr = new int;
        *ptr = *(t.ptr);
    }

    //delete func
    ~Test() {
        delete ptr;
        printf("deleted obj\n");
    }

};

void transfer(Test &obj);

Test return_obj(Test obj);

int main() {
    system("chcp 65001");
    int te = 10;
    Test t(te);
    transfer(t);
    return_obj(t);
    return 0;
}

void transfer(Test &obj) {
    cout << "ptr的地址:" << obj.ptr << "---ptr的值:" << *obj.ptr << endl;
}

Test return_obj(Test obj) {
    return obj;
}
输出:
Active code page: 65001
调用普通构造函数
ptr的地址:0xe71750---ptr的值:10
调用拷贝构造函数
调用拷贝构造函数
deleted obj
deleted obj
deleted obj

析构函数调用了三次,分别是析构掉普通构造函数,析构掉return_obj()当对象以值作为参数传入时调用的拷贝构造函数,析构掉当对象作为函数返回值时调用的拷贝构造函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值