MST
星途 面试题库

面试题:C++ 移动语义基础应用

在C++中,假设有一个自定义类 `MyClass`,包含一个动态分配的数组成员变量。请编写代码,通过移动语义实现将一个 `MyClass` 对象的资源高效转移到另一个对象中,并解释 `std::move` 在此过程中的作用。
49.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <memory>

class MyClass {
private:
    int* data;
    size_t size;

public:
    // 构造函数
    MyClass(size_t s) : size(s) {
        data = new int[s];
        for (size_t i = 0; i < s; ++i) {
            data[i] = i;
        }
    }

    // 析构函数
    ~MyClass() {
        delete[] data;
    }

    // 拷贝构造函数
    MyClass(const MyClass& other) : size(other.size) {
        data = new int[size];
        for (size_t i = 0; i < size; ++i) {
            data[i] = other.data[i];
        }
    }

    // 拷贝赋值运算符
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            delete[] data;
            size = other.size;
            data = new int[size];
            for (size_t i = 0; i < size; ++i) {
                data[i] = other.data[i];
            }
        }
        return *this;
    }

    // 移动构造函数
    MyClass(MyClass&& other) noexcept : size(other.size), data(other.data) {
        other.size = 0;
        other.data = nullptr;
    }

    // 移动赋值运算符
    MyClass& operator=(MyClass&& other) noexcept {
        if (this != &other) {
            delete[] data;
            size = other.size;
            data = other.data;
            other.size = 0;
            other.data = nullptr;
        }
        return *this;
    }
};

int main() {
    MyClass a(5);
    MyClass b = std::move(a);
    return 0;
}

std::move 在此过程中的作用

  1. 类型转换std::move 本质上是将左值转换为右值引用。在 MyClass b = std::move(a); 这行代码中,a 原本是一个左值(可以取地址的对象),std::move(a) 将其转换为右值引用。右值引用允许我们对临时对象进行操作,避免不必要的拷贝。
  2. 触发移动语义:当 MyClass 的移动构造函数或移动赋值运算符接收右值引用参数时,编译器会优先调用移动构造函数或移动赋值运算符(如果定义了的话)。这使得资源(如动态分配的数组)可以高效地从一个对象转移到另一个对象,而不是进行深拷贝。在移动构造函数和移动赋值运算符中,源对象的资源被“窃取”,源对象被置于一个可析构的有效但不确定的状态(size 设为0,data 设为 nullptr)。这样可以避免重复分配内存和拷贝数据,提高性能。