[英]Why is copy constructor being invoked when I return a heap allocated object but not for stack allocated object?
I have a state
class which has a move assignment/constructor.我有一个
state
类,它有一个移动分配/构造函数。 The copy assingment/constructor are set to delete
.副本分配/构造函数设置为
delete
。
I am confused why in the following function (which returns a state
object) compiles and runs fine like this:我很困惑为什么在下面的函数(它返回一个
state
对象)中编译并运行良好,如下所示:
state propagator::PROPAGATE(date & TargetDate)
{
jmethodID jmid_PROPAGATE = ENV->GetMethodID(this->jcls_PROPAGATOR, "propagate", "(path/to/date;)path/to/state;");
jobject jobj_PROPAGATED_STATE = ENV->CallObjectMethod(this->jobj_PROPAGATOR, jmid_PROPAGATE, TargetDate.get_DATE_JOBJECT());
state PROPAGATED_STATE(this->ENV);
PROPAGATED_STATE.set_STATE_JOBJECT(jobj_PROPAGATED_STATE);
return PROPAGATED_STATE;
//state * PROPAGATED_STATE = new state(ENV);
//PROPAGATED_STATE->set_STATE_JOBJECT(jobj_PROPAGATED_STATE);
//return *PROPAGATED_STATE;
}
but complains that copy constructor has been deleted when I try this:但抱怨当我尝试这个时复制构造函数已被删除:
state propagator::PROPAGATE(date & TargetDate)
{
jmethodID jmid_PROPAGATE = ENV->GetMethodID(this->jcls_PROPAGATOR, "propagate", "(path/to/date;)path/to/state;");
jobject jobj_PROPAGATED_STATE = ENV->CallObjectMethod(this->jobj_PROPAGATOR, jmid_PROPAGATE, TargetDate.get_DATE_JOBJECT());
//state PROPAGATED_STATE(this->ENV);
//PROPAGATED_STATE.set_STATE_JOBJECT(jobj_PROPAGATED_STATE);
//return PROPAGATED_STATE;
state * PROPAGATED_STATE = new state(ENV);
PROPAGATED_STATE->set_STATE_JOBJECT(jobj_PROPAGATED_STATE);
return *PROPAGATED_STATE;
}
Compiler output:编译器输出:
error: use of deleted function ‘state::state(const state&)’
Modern compilers are clever enough to do the RVO ( What are copy elision and return value optimization? )现代编译器足够聪明来执行 RVO( 什么是复制省略和返回值优化? )
state propagator::PROPAGATE(date & TargetDate)
{
jmethodID jmid_PROPAGATE = ENV->GetMethodID(this->jcls_PROPAGATOR, "propagate", "(path/to/date;)path/to/state;");
jobject jobj_PROPAGATED_STATE = ENV->CallObjectMethod(this->jobj_PROPAGATOR, jmid_PROPAGATE, TargetDate.get_DATE_JOBJECT());
state PROPAGATED_STATE(this->ENV);
PROPAGATED_STATE.set_STATE_JOBJECT(jobj_PROPAGATED_STATE);
return PROPAGATED_STATE;
}
That's why here we return actually the object which was created (compiler can just create it in place for function's return value, to avoid copying).这就是为什么在这里我们实际返回创建的对象(编译器可以为函数的返回值创建它,以避免复制)。
But in second variant you are trying to create object in the stack from object in the HEAP, and RVO or move can't be used here.但是在第二个变体中,您试图从 HEAP 中的对象创建堆栈中的对象,并且 RVO 或 move 不能在这里使用。 That's why it is trying to perform the deleted copy.
这就是它试图执行已删除副本的原因。
state propagator::PROPAGATE(date & TargetDate)
{
jmethodID jmid_PROPAGATE = ENV->GetMethodID(this->jcls_PROPAGATOR, "propagate", "(path/to/date;)path/to/state;");
jobject jobj_PROPAGATED_STATE = ENV->CallObjectMethod(this->jobj_PROPAGATOR, jmid_PROPAGATE, TargetDate.get_DATE_JOBJECT());
state * PROPAGATED_STATE = new state(ENV);
PROPAGATED_STATE->set_STATE_JOBJECT(jobj_PROPAGATED_STATE);
return *PROPAGATED_STATE;
}
Also you are leaking memory by discarding pointer to heap, where you've created an object.此外,您通过丢弃指向堆的指针来泄漏内存,在那里您创建了一个对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.