考虑这个程序本质上创建了<代码> STD::线程< /代码>,调用函数<代码>函数()/代码>以<代码> ARG作为参数:
#include <thread>
#include <iostream>
struct foo {
foo() = default;
foo(const foo&) { std::cout << "copy ctor" << std::endl; }
foo(foo&&) noexcept { std::cout << "move ctor" << std::endl; }
};
void func(foo){}
int main() {
foo arg;
std::thread th(func, arg);
th.join();
}
我的输出是
copy ctor
move ctor
move ctor
据我所知,arg
在线程对象中内部复制,然后作为右值(移动)传递给func()
。所以,我期待一个副本建设和一个移动建设。
为什么会有第二步建设?
所以,我期望一次复制构造和一次移动构造。
标准实际上并没有这么说。允许实现执行额外的内部移动构造。
但这样做可能会降低效率。这是https://gcc.gnu.org/PR69724并且已经在即将发布的GCC10版本中修复。
通过值将参数传递给func
,该值应构成第二步。显然,std::thread
在调用func
之前会在内部存储它一次,就标准而言,AFAIK是绝对合法的。
请考虑以下程序: 如果我运行该程序,我会得到(GoBolt): ...这符合我的预期。但是,如果在线上我将析构函数标记为可能抛出,那么我得到: ...即使用复制因子代替移动因子。为什么会这样呢?复制似乎不能防止移动所必须的破坏。 相关问题: < li >是否要求std::vector使用移动而不是复制? < li >当向量增长时,如何实施移动语义? < li >向量重新分配使用复制而不是移动构造函
问题内容: 我写了一个实现Runnable的类,以同时运行到另一个线程。主线程处理侦听串行端口,而第二个线程将处理向该端口发送数据。 第一个线程从第二个开始,如下所示: 这可行,但是我的编译器会标出警告语:在构造函数中启动新线程很危险。为什么是这样? 这个问题的第二部分是:如何在一个线程(串行端口侦听线程)中运行循环,并在第二个线程中键入退出命令。如何获得第一个终止的线程?谢谢。 问题答案: 你的
当Java中给出参数构造函数时,为什么默认的无参数构造函数会失败? 这个设计有什么意义? 例如:
问题内容: 必须使用无参数构造函数(像Hibernate这样的工具会在此构造函数上使用反射来实例化对象)。 我得到了这个手挥手的答案,但是有人可以进一步解释吗?谢谢 问题答案: hibernate,并且通常通过反射创建对象的代码用于创建类的新实例。此方法需要一个公共的无参数构造函数才能实例化该对象。对于大多数用例,提供无参数构造函数不是问题。 有一些基于序列化的技巧可以解决没有no-arg构造函数
在C#、C和Java中,当你创建一个带参数的构造函数时,默认的无参数构造函数就消失了。我一直只是接受这个事实,但现在我开始想为什么。 这种行为的原因是什么?这仅仅是一个“安全度量/猜测”,说“如果你已经创建了自己的构造函数,你可能不希望这个隐含的函数四处游荡”?或者它有一个技术原因,使得编译器不可能在你自己创建构造函数后添加一个?
我正试图用BlueJ完成一项为uni完成的任务,但我在第一个障碍上遇到了障碍。 在赋值中,我们得到了一个类,以及该类的构造函数、方法和参数的名称。我们不允许更改这些,因为赋值部分地由测试单元标记(或类似的东西)。 该类的一个构造函数如下所示 我已经(部分)完成了 我不明白的是为什么-为什么他们使用作为构造函数的参数?这样做有什么好处? (我想这样做肯定有好处(如果没有,功能就不会存在),但我不明白