使用类的成员函数作为 std::thread 参数
-
- [1. 基本使用方法](#1. 基本使用方法)
-
- [1.1 静态成员函数](#1.1 静态成员函数)
- [1.2 非静态成员函数](#1.2 非静态成员函数)
- [2. 详细参数传递方式](#2. 详细参数传递方式)
-
- [2.1 基本语法](#2.1 基本语法)
- [2.2 各种对象传递方式](#2.2 各种对象传递方式)
- [3. Lambda 表达式](#3. Lambda 表达式)
- [4. 注意事项和常见问题](#4. 注意事项和常见问题)
-
- [4.1 对象生命周期管理](#4.1 对象生命周期管理)
- [4.2 成员函数访问控制](#4.2 成员函数访问控制)
- [4.3 带返回值的成员函数](#4.3 带返回值的成员函数)
- [5. 最佳实践总结](#5. 最佳实践总结)
1. 基本使用方法
1.1 静态成员函数
静态成员函数与普通函数类似,可以直接作为线程参数:
cpp
#include <iostream>
#include <thread>
class MyClass {
public:
static void static_func(int x) {
std::cout << "静态函数: " << x << std::endl;
}
};
int main() {
std::thread t(&MyClass::static_func, 10);
t.join();
return 0;
}
1.2 非静态成员函数
非静态成员函数需要对象实例作为上下文:
cpp
#include <iostream>
#include <thread>
class Worker {
public:
void process(int id) {
std::cout << "Worker " << id << " 处理中..." << std::endl;
}
};
int main() {
Worker worker;
// 方法1:传递对象实例
std::thread t1(&Worker::process, &worker, 1);
// 方法2:传递对象副本(需要可复制)
std::thread t2(&Worker::process, worker, 2);
t1.join();
t2.join();
return 0;
}
2. 详细参数传递方式
2.1 基本语法
cpp
std::thread t(&ClassName::MemberFunction, object_instance, arg1, arg2, ...);
2.2 各种对象传递方式
cpp
class Calculator {
public:
void add(int a, int b) {
std::cout << a << " + " << b << " = " << (a + b) << std::endl;
}
};
int main() {
Calculator calc;
// 1. 传递指针(常用)
std::thread t1(&Calculator::add, &calc, 10, 20);
// 2. 传递引用(使用 std::ref)
std::thread t2(&Calculator::add, std::ref(calc), 30, 40);
// 3. 传递智能指针
auto ptr = std::make_unique<Calculator>();
std::thread t3(&Calculator::add, ptr.get(), 50, 60);
// 4. 传递对象副本(需要可复制)
Calculator calc2;
std::thread t4(&Calculator::add, calc2, 70, 80);
t1.join(); t2.join(); t3.join(); t4.join();
return 0;
}
3. Lambda 表达式
cpp
class DataProcessor {
private:
int data_;
public:
DataProcessor(int data) : data_(data) {}
void complex_process() {
// 复杂的处理逻辑
std::cout << "处理数据: " << data_ << std::endl;
}
};
int main() {
DataProcessor processor(100);
// 使用lambda
std::thread t([&processor]() {
processor.complex_process();
});
t.join();
return 0;
}
4. 注意事项和常见问题
4.1 对象生命周期管理
cpp
class Task {
public:
void run() {
std::cout << "执行任务" << std::endl;
}
};
void problematic_example() {
std::thread t;
{
Task task; // 局部对象
t = std::thread(&Task::run, &task); // 危险!task很快会被销毁
} // task在这里被销毁
t.join(); // 访问已销毁对象!
}
void safe_example() {
// 方法1:使用动态分配
auto task = std::make_shared<Task>();
std::thread t(&Task::run, task); // 共享所有权
// 方法2:确保对象生命周期
Task task2;
std::thread t2(&Task::run, &task2);
t2.join(); // 在task2销毁前join
t.join();
}
4.2 成员函数访问控制
cpp
class SecureClass {
private:
void private_func() {
std::cout << "私有函数" << std::endl;
}
public:
void public_func() {
// 可以通过公有函数间接调用私有函数
std::thread t(&SecureClass::private_func, this);
t.join();
}
static void wrapper(SecureClass* obj) {
obj->private_func();
}
};
4.3 带返回值的成员函数
cpp
#include <future>
class Math {
public:
int square(int x) {
return x * x;
}
};
int main() {
Math math;
// 使用 std::async 获取返回值
auto future = std::async(&Math::square, &math, 5);
int result = future.get();
std::cout << "结果: " << result << std::endl;
return 0;
}
5. 最佳实践总结
- 对象生命周期管理:确保线程执行期间对象保持有效
- 使用智能指针 :推荐使用
std::shared_ptr管理对象生命周期 - Lambda 表达式:复杂场景下使用 lambda 更灵活
- 异常安全:确保线程在异常情况下也能正确结束
- 资源清理:确保所有线程在对象销毁前 join 或 detach
cpp
class SafeThreadHandler {
private:
std::thread worker_;
void worker_func() {
try {
// 工作逻辑
} catch (...) {
// 异常处理
}
}
public:
SafeThreadHandler() {
worker_ = std::thread(&SafeThreadHandler::worker_func, this);
}
~SafeThreadHandler() {
if (worker_.joinable()) {
worker_.join();
}
}
// 禁用复制
SafeThreadHandler(const SafeThreadHandler&) = delete;
SafeThreadHandler& operator=(const SafeThreadHandler&) = delete;
};