Почему конструктор копирования вызывается, когда я возвращаю выделенный объект кучи, но не для выделенного объекта стека?
У меня есть state
класс, который имеет задание на перемещение / конструктор. Копирование / конструктор установлены на delete
,
Я запутался, почему в следующей функции (которая возвращает state
object) компилируется и работает так:
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;
}
но жалуется, что конструктор копирования был удален, когда я пытаюсь это:
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;
}
Выход компилятора:
error: use of deleted function ‘state::state(const state&)’
1 ответ
Современные компиляторы достаточно умны, чтобы выполнять 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;
}
Вот почему здесь мы возвращаем фактически созданный объект (компилятор может просто создать его на месте для возвращаемого значения функции, чтобы избежать копирования).
Но во втором варианте вы пытаетесь создать объект в стеке из объекта в HEAP, и здесь нельзя использовать 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 = new state(ENV);
PROPAGATED_STATE->set_STATE_JOBJECT(jobj_PROPAGATED_STATE);
return *PROPAGATED_STATE;
}
Также вы теряете память, отбрасывая указатель на кучу, где вы создали объект.