C++学习笔记3:拷贝构造和移动构造

一、拷贝构造函数

 1、拷贝构造函数的语法:
        拷贝构造函数名字(const 类名& ) {}

        拷贝构造函数名字 -> 类名
        形参列表:拷贝构造函数的第一个参数必须是本类对象的 const引用。
                   如果还需要其他的参数,那么必须要设置默认值(c++ 11新标准)

当没有实现拷贝构造函数的时候,编译器会自动生成一个,函数体内不是为空,而是执行逐个成员赋值

以自己简单实现的string类来举例:

class Mystring {
private:
    char *m_ptr;
    int m_size;
public:
    /* 普通构造函数 */
    Mystring(const char *m_ptr);
    /* 拷贝构造函数 */
    Mystring(const Mystring& other);
    /* 移动构造函数 */
    Mystring(Mystring&& other);
    /* 析构函数 */
    ~Mystring();
    void show() const;
    int get_size() const;
};

/* 拷贝构造函数 */
Mystring::Mystring(const Mystring &other) {
   m_ptr = new char[other.m_size + 1];
   memcpy(m_ptr, other.m_ptr, other.m_size);
   m_size = other.m_size;

#ifdef DEBUG
    cout << "拷贝构造函数运行中" << endl;
#endif
}

 思考:
        拷贝构造函数的参数,为什么是本类对象的 const引用?
            引用:提高效率。更重要的是如果不用引用传递,就会陷入无限拷贝中(实参传递给形参的过程又会调用拷贝构造函数)
            const是为了不让原对象被修改

2、深拷贝和浅拷贝

 

Mystring::Mystring(const Mystring &other) {
//m_ptr = other.m_ptr; 浅拷贝
    m_ptr = new char[other.m_size + 1]; //深拷贝
    memcpy(m_ptr, other.m_ptr, other.m_size);
    m_size = other.m_size;
}
分配新的堆区空间,而不是指向同一段堆区空间,这种为新对象分配资源的情况称之为深拷贝

拷贝构造函数被调用的具体时机
    总的来说:用一个已有对象初始化一个新对象时会调用拷贝构造函数

    1,直接初始化

Mystring str{"hello"};

Mystring str1{str};
//Mystring str1 = str;
    str1.show();
    cout << str1.get_size() << endl;

   2, 一个对象作为参数,以值传递的方式传入函数内

void func(Mystring str) {
    str.show();
}

Mystring str{"hello"};
func(str);

   3, 一个函数返回class类型的对象

Mystring func() {
    Mystring str{"hello world"};
    return str;
}

Mystring str2 = func();
    str2.show();
    cout << str2.get_size() << endl;

二、移动构造函数

一个函数返回一个class对象时,本来会调用拷贝构造函数,但是经过编译器优化之后就没有调用拷贝构造函数了。
    怎么优化的?? 不调用拷贝构造而是调用移动构造函数
    如果程序员自己不实现移动构造函数,编译器就会默认生成一个移动构造函数

 移动构造函数语法:
        移动构造函数名(类名 && other)
        {}

        移动构造函数名:类名
        &&  右值引用

Mystring::Mystring(Mystring &&other) {
   m_ptr = other.m_ptr;
   other.m_ptr = nullptr;
   m_size = other.m_size;

#ifdef DEBUG
    cout << "移动构造函数运行中" << endl;
#endif
}

移动构造函数的原理:

 移动构造和拷贝构造:
        对于新对象最终结果一样,实现过程不一样,提高了效率
        对于原对象,拷贝构造之后还拥有资源,移动构造之后不再拥有资源
    既有拷贝构造又有移动构造时,编译器如何选择:
        用右值对象(临时对象/即将销毁的对象)去初始化 新对象时  ->调用移动构造
        用左值对象去初始化新对象时 ->调用拷贝构造 

  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值