C++类移动

发布于:2025-04-06 ⋅ 阅读:(31) ⋅ 点赞:(0)

目录

对象移动

移动构造函数

移动赋值运算符

合成的移动操作


对象移动

对象移动是 C++11 引入的核心特性,旨在通过转移资源所有权而非复制内容来提升性能。

移动构造函数

class Base { 

public:

    Base() : m_value(100) { 

        //std::cout << "类构造函数执行" << std::endl;

    }

    Base(const Base& other) : m_value(other.m_value) {}

    virtual ~Base() {

        //std::cout << "类的析构函数执行" << std::endl;

    }

    int m_value; 

};

class BaseOwner { 

public:

    BaseOwner() : m_basePtr(new Base()) { 

        std::cout << "构造函数执行" << std::endl; 

    }

    BaseOwner(const BaseOwner& other) : m_basePtr(new Base(*(other.m_basePtr))) {

        std::cout << "类的拷贝构造函数" << std::endl; 

    }

    //移动构造函数

    BaseOwner(BaseOwner&& other)noexcept :m_basePtr(other.m_basePtr)

    {

        other.m_basePtr = nullptr;

        std::cout << "移动构造函数" << std::endl;

    }

    virtual ~BaseOwner() {

        delete m_basePtr; 

        std::cout << "析构函数执行" << std::endl;

    }

private:

    Base* m_basePtr; 

};

noexcept是我们承诺一个函数不抛出异常的一种方法。我们在一个函数的参数列表后指定 noexcept。在一个构造函数中,noexcept出现在参数列表和初始化列表开始的冒号之间。一般情况下,移动构造函数都需要加

static BaseOwner get()

{

    BaseOwner tmp;

    return tmp;

}



int main()

{

    //BaseOwner t = get();

    BaseOwner t2 = (std::move(get()));

    return 0;

}

这里使用std::move就会调用移动构造函数,而上一行代码在现版本的编译器优化下,已经不再调用拷贝构造函数。

而是直接将被返回的局部对象(tmp)构造到目标内存(t)中。

移动赋值运算符

下面我们为类BaseOwner增加拷贝赋值运算符和移动赋值运算符,参数上前者是左值引用后者是右值引用  

 BaseOwner& operator=(const BaseOwner& src)

    {

        if (this == &src)

            return *this;



        delete m_basePtr;

        m_basePtr = new Base((*src.m_basePtr));

        std::cout << "BaseOwner拷贝赋值运算符执行" << std::endl;

        return *this;

    }



    BaseOwner& operator=(BaseOwner&& src)

    {

        if (this == &src)

            return *this;



        delete m_basePtr;

        m_basePtr = src.m_basePtr;

        src.m_basePtr = nullptr;

        std::cout << "BaseOwner的移动赋值运算符执行" << std::endl;

        return *this;

    }

运行如下代码,我们将会调用移动赋值运算符

    BaseOwner t3;

    t3 = std::move(get());

合成的移动操作

当一个类没有定义任何自己版本的拷贝控制成员(包括拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符、析构函数),且类的每个非static数据成员都可以移动时,编译器才会为它合成移动构造函数或移动赋值运算符。编译器可以移动内置类型的成员。如果一个成员是类类型,且该类有对应的移动操作,编译器也能移动这个成员。


网站公告

今日签到

点亮在社区的每一天
去签到