美文网首页
C++ move构造函数和move赋值

C++ move构造函数和move赋值

作者: Little熊猫 | 来源:发表于2018-09-07 17:07 被阅读0次

看一下下面这个例子

template<class T>
class Auto_ptr3
{
    T* m_ptr;
public:
    Auto_ptr3(T* ptr = nullptr)
        :m_ptr(ptr)
    {
    }
 
    ~Auto_ptr3()
    {
        delete m_ptr;
    }
 
    // Copy constructor
    // Do deep copy of a.m_ptr to m_ptr
    Auto_ptr3(const Auto_ptr3& a)
    {
        m_ptr = new T;
        *m_ptr = *a.m_ptr;
    }
 
    // Copy assignment
    // Do deep copy of a.m_ptr to m_ptr
    Auto_ptr3& operator=(const Auto_ptr3& a)
    {
        // Self-assignment detection
        if (&a == this)
            return *this;
 
        // Release any resource we're holding
        delete m_ptr;
 
        // Copy the resource
        m_ptr = new T;
        *m_ptr = *a.m_ptr;
 
        return *this;
    }
 
    T& operator*() const { return *m_ptr; }
    T* operator->() const { return m_ptr; }
    bool isNull() const { return m_ptr == nullptr; }
};
 
class Resource
{
public:
    Resource() { std::cout << "Resource acquired\n"; }
    ~Resource() { std::cout << "Resource destroyed\n"; }
};
 
Auto_ptr3<Resource> generateResource()
{
    Auto_ptr3<Resource> res(new Resource);
    return res; // this return value will invoke the copy constructor
}
 
int main()
{
    Auto_ptr3<Resource> mainres;
    mainres = generateResource(); // this assignment will invoke the copy assignment
 
    return 0;
}

输出:

Resource acquired
Resource acquired
Resource destroyed
Resource acquired
Resource destroyed
Resource destroyed

好多构造函数和析构函数执行,下面分析一下每个打印代表的步骤
1)nside generateResource() new Resource构造函数调用
2)generateResource 返回main,res调用copy构造函数给一个临时变量

  1. res在generateResource退出后调用析构函数
    4)临时变量调用copy构造函数给mainres
  2. 临时变量调用析构函数
  3. main退出,mainres 调用析构函数
    优化如下:
#include <iostream>
 
template<class T>
class Auto_ptr4
{
    T* m_ptr;
public:
    Auto_ptr4(T* ptr = nullptr)
        :m_ptr(ptr)
    {
    }
 
    ~Auto_ptr4()
    {
        delete m_ptr;
    }
 
    // Copy constructor
    // Do deep copy of a.m_ptr to m_ptr
    Auto_ptr4(const Auto_ptr4& a)
    {
        m_ptr = new T;
        *m_ptr = *a.m_ptr;
    }
 
    // Move constructor
    // Transfer ownership of a.m_ptr to m_ptr
    Auto_ptr4(Auto_ptr4&& a)
        : m_ptr(a.m_ptr)
    {
        a.m_ptr = nullptr; // we'll talk more about this line below
    }
 
    // Copy assignment
    // Do deep copy of a.m_ptr to m_ptr
    Auto_ptr4& operator=(const Auto_ptr4& a)
    {
        // Self-assignment detection
        if (&a == this)
            return *this;
 
        // Release any resource we're holding
        delete m_ptr;
 
        // Copy the resource
        m_ptr = new T;
        *m_ptr = *a.m_ptr;
 
        return *this;
    }
 
    // Move assignment
    // Transfer ownership of a.m_ptr to m_ptr
    Auto_ptr4& operator=(Auto_ptr4&& a)
    {
        // Self-assignment detection
        if (&a == this)
            return *this;
 
        // Release any resource we're holding
        delete m_ptr;
 
        // Transfer ownership of a.m_ptr to m_ptr
        m_ptr = a.m_ptr;
        a.m_ptr = nullptr; // we'll talk more about this line below
 
        return *this;
    }
 
    T& operator*() const { return *m_ptr; }
    T* operator->() const { return m_ptr; }
    bool isNull() const { return m_ptr == nullptr; }
};
 
class Resource
{
public:
    Resource() { std::cout << "Resource acquired\n"; }
    ~Resource() { std::cout << "Resource destroyed\n"; }
};
 
Auto_ptr4<Resource> generateResource()
{
    Auto_ptr4<Resource> res(new Resource);
    return res; // this return value will invoke the move constructor
}
 
int main()
{
    Auto_ptr4<Resource> mainres;
    mainres = generateResource(); // this assignment will invoke the move assignment
 
    return 0;
}

输出:

Resource acquired
Resource destroyed

1)第一步同上
2)函数返回,保存返回值给临时变量,调用move constructed函数,只进行指针copy
3)函数返回,res回收,由于res不指向任何值,因此没操作
4)临时变量赋值给mainres,同第2不
5)main退出,临时变量不指向任何值,无操作
6)main退出,mainres 调用析构函数"Resource destroyed"执行

那么什么条件下执行copy构造函数,什么情况下调用Move构造函数
1) 如果我们给一个l-value赋值的时候,调用copy构造函数
2)如果给一个r-value赋值的时候,调用Move构造函数,因为r-value都是临时的,将要被销毁的
在上面的例子中,generateResource()函数返回值调用的是move构造函数,而不是copy构造函数,跟第一条不符?C++定义函数返回值是调用move即使是给l-value复制。

相关文章

  • C++ move构造函数和move赋值

    看一下下面这个例子 输出: 好多构造函数和析构函数执行,下面分析一下每个打印代表的步骤1)nside genera...

  • [字符串] 自己实现一个string类(一)

    C++类一般包括:构造函数,拷贝构造函数,赋值构造函数和析构函数四大函数。 在上面的赋值构造函数中,都是先dele...

  • c++学习笔记2(GeekBand)

    拷贝构造、拷贝赋值和析构 c++中有Big Three三个特殊的函数,他们就是拷贝构造函数,拷贝赋值函数和析构函数...

  • 智能指针

    std::unique_ptr<> 初始化:直接初始化、右值赋值、std::move作为函数返回值作为函数形参

  • Boolan第二周笔记

    一、C++三个特殊的函数(Big Three):拷贝构造函数,赋值构造函数和析构函数 class里面只要有指针,就...

  • C++拷贝控制

    前言 C++通过在类中定义几个成员函数来控制的对象的拷贝,移动,赋值和销毁,分别如下: 拷贝构造函数和移动构造函数...

  • 第十章 对象和类(3)类的构造函数和析构函数

    (三)类的构造函数和析构函数 c++提供了一种特殊的成员函数,称为类构造函数,专门用于构造新对象,将值赋值给它的...

  • 全面梳理 C++ 拷贝构造与赋值运算符重载(operator=)

    本文全面梳理 C++ 的拷贝构造与赋值运算符重载(operator=) 默认拷贝构造函数和赋值运算符 在默认情况下...

  • 【move】2.Move Tutorial

    Move 教程(Move Tutorial) Welcome to the Move Tutorial! In t...

  • effective C++ 总结

    构造,析构和赋值 C++编译器会默认为每个类创建三个成员函数 一个拷贝构造函数(如果没有声明) 一个copy赋值操...

网友评论

      本文标题:C++ move构造函数和move赋值

      本文链接:https://www.haomeiwen.com/subject/nkncgftx.html