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