MST

星途 面试题库

面试题:C++ 移动语义在复杂场景中的应用

在一个多线程环境下,一个`std::vector`中存放了自定义类型`MyClass`对象,`MyClass`支持移动语义。现在需要从`std::vector`中删除特定条件的`MyClass`对象,并将删除的对象移动到另一个`std::vector`中。请描述可能遇到的问题以及如何利用移动语义和合适的线程同步机制(如`std::mutex`)来实现高效且线程安全的操作。同时,给出关键代码示例。
48.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

可能遇到的问题

  1. 数据竞争:多个线程同时访问和修改std::vector可能导致数据不一致。例如,一个线程正在删除元素,而另一个线程试图访问或修改相同位置的元素。
  2. 迭代器失效:在删除std::vector中的元素时,迭代器可能会失效。如果在多线程环境下,一个线程删除元素导致迭代器失效,而另一个线程还在使用该失效的迭代器,会引发未定义行为。

利用移动语义和线程同步机制实现

  1. 移动语义:利用MyClass支持的移动语义,可以避免不必要的对象拷贝,提高效率。在将对象从一个std::vector移动到另一个std::vector时,使用std::move
  2. 线程同步机制:使用std::mutex来保护对std::vector的访问。在访问或修改std::vector之前,锁定对应的mutex,操作完成后解锁。

关键代码示例

#include <iostream>
#include <vector>
#include <mutex>

class MyClass {
public:
    MyClass() = default;
    MyClass(const MyClass&) = default;
    MyClass(MyClass&&) noexcept = default;
    MyClass& operator=(const MyClass&) = default;
    MyClass& operator=(MyClass&&) noexcept = default;
    ~MyClass() = default;
};

std::mutex vecMutex;

void removeAndMove(std::vector<MyClass>& source, std::vector<MyClass>& target, const auto& condition) {
    std::lock_guard<std::mutex> lock(vecMutex);
    auto it = source.begin();
    while (it != source.end()) {
        if (condition(*it)) {
            target.emplace_back(std::move(*it));
            it = source.erase(it);
        } else {
            ++it;
        }
    }
}

你可以这样调用上述函数:

int main() {
    std::vector<MyClass> source;
    std::vector<MyClass> target;

    // 填充source向量
    source.emplace_back();
    source.emplace_back();

    auto condition = [](const MyClass& obj) {
        // 这里编写具体的删除条件
        return true;
    };

    removeAndMove(source, target, condition);

    return 0;
}

在上述代码中,removeAndMove函数使用std::lock_guard来自动管理std::mutex的锁定和解锁。在锁定mutex后,遍历source向量,满足条件的MyClass对象通过std::move移动到target向量中,并从source向量中删除。这样既保证了线程安全,又利用了移动语义提高效率。