C++ 将点传递到线程中并对其进行修改
我需要将对象的引用传递到线程中。按照环境的设置方式,我必须将特定于应用程序的图形保持在启动时的同一线程中。所以我把appinit代码塞进一个线程中,然后得到一个我感兴趣的自定义组件的引用 这不管用。应用程序加载并显示良好,但主线程中指向应用程序的指针始终为C++ 将点传递到线程中并对其进行修改,c++,multithreading,C++,Multithreading,我需要将对象的引用传递到线程中。按照环境的设置方式,我必须将特定于应用程序的图形保持在启动时的同一线程中。所以我把appinit代码塞进一个线程中,然后得到一个我感兴趣的自定义组件的引用 这不管用。应用程序加载并显示良好,但主线程中指向应用程序的指针始终为null。即使我使用std::shared_ptr或std::ref。不管我做什么,指针总是空的 #include <thread> #include <iostream> class SomeClass { publ
null
。即使我使用std::shared_ptr
或std::ref
。不管我做什么,指针总是空的
#include <thread>
#include <iostream>
class SomeClass {
public:
int value;
SomeClass() { value = 0; }
};
void ExecuteThread(SomeClass* c) {
c = new SomeClass();
c->value = 555;
}
int main(int argc, char** argv) {
SomeClass* c = nullptr;
// std::ref(c) doesn't work
// Have also tried passing std::shared_ptr<SomeClass>
std::thread t1 = std::thread(&ExecuteThread, c);
t1.join();
std::cout << "c: " << c << "\n";
std::cout << "c->value: " << c->value << "\n";
return 0;
}
#包括
#包括
上课{
公众:
int值;
SomeClass(){value=0;}
};
void ExecuteThread(SomeClass*c){
c=新的SomeClass();
c->value=555;
}
int main(int argc,字符**argv){
SomeClass*c=nullptr;
//标准::参考(c)不起作用
//还尝试通过std::shared\u ptr
std::thread t1=std::thread(&ExecuteThread,c);
t1.join();
std::coutstd::thread
会秘密复制作为参数传递的所有内容,包括指针数据。这是令人难以置信的误导。唯一的解决方法是将地址传递给指针,并让线程复制该地址。然后在线程的任务中,遵从指针
#include <thread>
#include <iostream>
class SomeClass {
public:
int value;
SomeClass() { value = 0; }
};
void ExecuteThread(SomeClass** c) {
*c = new SomeClass();
*c->value = 555;
}
int main(int argc, char** argv) {
SomeClass* c = nullptr;
std::thread t1 = std::thread(&ExecuteThread, &c);
t1.join();
std::cout << "c: " << c << "\n";
std::cout << "c->value: " << c->value << "\n";
return 0;
}
#包括
#包括
上课{
公众:
int值;
SomeClass(){value=0;}
};
void ExecuteThread(SomeClass**c){
*c=新的SomeClass();
*c->value=555;
}
int main(int argc,字符**argv){
SomeClass*c=nullptr;
std::thread t1=std::thread(&ExecuteThread,&c);
t1.join();
std::cout为了让人们不会被错误的自我回答弄糊涂,我提供了我自己的正确答案
OPs代码的主要问题是逐值传递指针会复制指针,对指针的任何修改都不会影响原始指针。线程不会更改此事实,也不会向其添加任何内容。特别是,代码可以如下所示
void change(int* k) {
k = nullptr;
}
int i;
k = &i;
change(k);
// k here is still the same as before calling `change`
如果要更改传递的指针,则应将其作为引用传递:void change(int*&k)
在这里使用线程会稍微改变一些事情。由于无法通过引用将某些内容传递给std::thread
构造函数,因此需要使用std::ref
。函数签名仍应通过引用接受指针,并且在创建线程的位置应使用std::ref
:
auto t = std::thread(change, std::ref(k))
你误解了复制指针的作用。你有两个Canvas
指针,而你只更改了其中一个。@Rinatvelikhmedov我确实提到了我为什么需要这样做。@DrewDormann这是一个指针,而不是一个值。即使我在指针周围使用std::ref
时,问题也是一样的。你能用Qt到底出了什么?@Maverick在你展示的代码中,你有两个不同的指针。改变一个并不改变另一个。(你的问题与Qt无关,而是指针如何工作。)我不能用std::ref
来评论你代码中的错误,因为我看不到它。@SergeyA我用一个带有一个成员变量的类为这个问题编写了一个测试平台。同样的问题。因此它与QT无关。无论我如何尝试将引用传递给新线程,似乎std::thread都会复制。这是令人难以置信的误导我花了几个小时在线寻找传递指针和在线共享指针的方法,这就是他们说的对线程所做的。不,任何地方都没有秘密副本。您的原始代码接受按值指针,所以对它的任何修改都丢失了。没有线程也没什么不同。@Maverick您在说什么?按值传递指针当两个代表人数在30K左右的人告诉一个代表人数为82的人这个人是错的时,这个人重新考虑通常是明智的。但是,你可以根据自己的情况。对于那些标记这个答案的主持人:不要仅仅因为你认为答案是错的就标记答案。主持人不会参与such.@Maverick该代码段调用未定义的行为是因为您取消引用空指针(并且在IDEOne上导致“运行时错误”):