简体   繁体   English

为什么当我返回堆分配的对象而不是堆栈分配的对象时调用复制构造函数?

[英]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.

相关问题 是否将堆分配的对象上的数据成员分配到堆或堆栈上? - Will data members on a heap-allocated object be allocated on the heap or the stack? 为什么在堆上分配对象时不调用复制构造函数? - Why is the copy constructor not called when objects are allocated on heap? C++:为什么对堆栈分配对象的引用与对堆分配对象的引用相同? - C++ : Why reference to stack allocated object treated same as reference to heap allocated object? 当在函数内部静态构造对象时,它将分配在堆还是堆栈上? - When object is constructed statically inside a function, would it be allocated on the heap or on the stack? 在堆栈或堆c ++上分配的对象 - Object allocated on stack or heap c++ 区分堆栈上分配的对象与堆对象 - Differentiating an object allocated on the stack from a heap obect 堆分配的对象可以在堆栈上移动吗? - Can heap allocated object be move on the stack? 包装堆栈分配的对象时如何避免复制/内存开销? - How to avoid copy/memory overhead when wrapping a stack allocated object? 初始化堆分配的对象时出错 - Error when initializing heap-allocated object 堆分配对象中的堆栈对象在c ++中的位置分配在哪里? - Where does a stack object inside a heap allocated object gets allocated in c++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM