在java中,我有以下生成的代码:
public class B {
public void exec(){
X x = (X) Thread.currentThread();
System.out.println(x.value);
}
}
public class X extends Thread{
public int value;
public X(int x){
value = x;
}
public void run(){
B b = new B();
b.exec();
}
}
new X(4).start();
B exec()方法检索与当前Thread(也是类X的实例)对应的字段值。
有没有办法在C ++中模拟相同的行为?注意:我不想将x作为参数传递给B实例,因为代码已生成。
class B {
public:
void exec();
};
class X {
public:
int value;
X(int x) {
value = x;
}
void run() {
B * b = new B();
b->exec();
}
};
void B::exec() {
std::cout << ??? << std::endl;
}
int main() {
X * x = new X(3);
boost::thread thr(boost::bind(&X::run, x));
thr.join();
}
我不知道如何检索与线程相关的类实例(我知道我没有),有什么想法吗?
答案 0 :(得分:4)
如果您不想将参数传递给B(这可能是最干净的解决方案),您可以使用线程本地存储。
一般来看你的代码,通过尝试从Java到C ++的这种严格的一对一映射,你可能会在自己的脚下拍摄。
在C ++中,你几乎不应该调用new
。尽可能在堆栈上分配。 C ++中的new
显然容易出错(没有垃圾回收),但与Java等托管语言相比,它也非常慢。
Functors可以用作函数指针的更强大的替代方法(例如在创建线程时),或者仅用于替换泛型exec()
或run()
函数。将它们命名为operator()
,该类可以用作仿函数。
在构造函数中,您应尽可能使用初始化列表。
以下建议适用于您的代码。当然我将参数传递给B构造函数。如果这不是一个选项,请改用thread local storage。
class B {
public:
explicit B(int value) : value(value)
void operator()();
private:
int value;
};
class X {
public:
int value;
X(int x) :value(x) { }// use the initializer list to initialize members
void operator()() {
B b(value); // allocate B on the stack if possible
b();
}
};
void B::operator()() {
std::cout << value << std::endl;
}
int main() {
boost::thread thr(X(3));
thr.join();
}
当然在这个简单的例子中,你首先不需要两个类。你可以很容易地完全删除X
并完成:
class B {
public:
explicit B(int value) : value(value)
void operator()();
private:
int value;
};
void B::operator()() {
std::cout << value << std::endl;
}
int main() {
boost::thread thr(B(3));
thr.join();
}
答案 1 :(得分:2)
确实,你不能(或不应该)继承boost::thread
。您可以使用thread-local storage来放置自己特定于线程的内容。
可以说,您应该对Java代码使用相同的技术。为此目的,Java有ThreadLocal
。