MST

星途 面试题库

面试题:C++ 右值引用兼容性与类成员函数

定义一个类 `MyClass`,包含一个成员函数 `MyClass&& moveSelf()`,该函数返回自身的右值引用。同时定义另一个成员函数 `void swap(MyClass&& other)` 用于交换当前对象和传入对象的数据成员。请实现这两个函数,并阐述在调用 `swap` 函数时,右值引用的兼容性是如何体现的,以及可能遇到的陷阱。
10.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

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

class MyClass {
private:
    int data;
public:
    MyClass(int value) : data(value) {}

    MyClass&& moveSelf() {
        return std::move(*this);
    }

    void swap(MyClass&& other) {
        std::swap(data, other.data);
    }
};

右值引用兼容性体现

在调用 swap 函数时,传入的参数是右值引用 MyClass&& other。这意味着可以传入一个临时对象(右值),例如 MyClass(10).swap(MyClass(20))。右值引用允许我们高效地处理临时对象,避免不必要的拷贝。当传入右值时,swap 函数能够直接操作右值对象的数据成员,而不需要额外的拷贝构造或赋值操作。

可能遇到的陷阱

  1. 悬空引用:如果在 swap 函数内部对传入的右值引用 other 进行了某些操作,导致 other 在函数结束后变为悬空引用,那么后续对 other 的使用将导致未定义行为。例如,如果 swap 函数中对 other 进行了释放内存的操作,而调用者在函数结束后试图访问 other 的数据成员,就会出现问题。
  2. 移动语义误用:如果 MyClass 类的数据成员包含指针类型,并且没有正确实现移动构造函数和移动赋值运算符,在 swap 函数中使用 std::swap 可能导致数据所有权转移错误。例如,原本期望的是移动语义,但由于未正确实现,实际执行的是拷贝语义,这可能导致内存泄漏或性能问题。
  3. 未考虑异常安全:如果 swap 函数中的操作可能抛出异常,并且没有进行适当的异常处理,可能会导致对象处于不一致的状态。例如,在交换过程中,如果某个操作抛出异常,而对象的数据成员已经部分交换,那么对象可能处于无效状态。为了确保异常安全,需要在 swap 函数中使用适当的异常处理机制,例如使用 try - catch 块,或者确保 std::swap 操作是异常安全的。