微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

即使在禁用RVO时定义了move构造函数,也会发生对象复制

如何解决即使在禁用RVO时定义了move构造函数,也会发生对象复制

我碰巧发现了一种情况,我正在按值从函数中返回对象。

在return语句中使用条件语句,可以避免RVO

代码如下:

#include <iostream>
#include <cstring>

class myObject {
    public:
    myObject() {
        std::cout <<"Default Constructor called" << std::endl;
        buffer = new char[1000];
        this->sz = 1000;
    }
    myObject(std::size_t sz) {
        buffer = new char[sz];
        this->sz = sz;
    }
    myObject(const myObject& other) {
        std::cout <<"copy Constructor called" << std::endl;
        buffer = new char[other.sz];
        sz = other.sz;
        std::memcpy(buffer,other.buffer,other.sz);
    }

    myObject(myObject&& other) noexcept {
        std::cout <<"Move Constructor called" << std::endl;
        buffer = other.buffer;
        sz = other.sz;
        other.buffer = NULL;
        other.sz = 0;
    }
    myObject& operator=(myObject&& other) noexcept {
        std::cout <<"Move Assignment called" << std::endl;
        if(buffer != NULL) {
            delete[] buffer;
            sz = 0;
        }
        buffer = other.buffer;
        sz = other.sz;
        other.buffer = NULL;
        other.sz = 0;
        
        return *this;
    }
    
    myObject& operator=(const myObject& other) {
        // self ref ignored
        std::cout <<"copy Assignment called" << std::endl;
        if(buffer != NULL) {
            delete[] buffer;
            sz = 0;
        }
        buffer = new char[other.sz];
        sz = other.sz;
        std::memcpy(buffer,other.sz);
        return *this;
    }
    ~myObject() {
        std::cout <<"~myObject()" << std::endl;
        if(buffer != NULL) {
            delete[] buffer;
            buffer = NULL;
        }
    }
    char * buffer = NULL;
    std::size_t sz = 0;
};


myObject Getobject_Complex(int x,int y) {
    myObject obj;
    myObject d;
    return x > y ? obj : d; // intentionaly made conditional to avoid Return value optimization
}

int main() {

    myObject c = Getobject_Complex(1,0); // Why move constructor is not called here ?

    std::cout << std::endl << std::endl;

    myObject d = std::move(c);
    std::cout << std::endl << std::endl;

    myObject e;
    std::cout << std::endl << std::endl;
    e = std::move(d);

}

这里使用g++ -g -std=c++11 gcc version 7.5.0

输出
Default Constructor called
Default Constructor called
copy Constructor called
~myObject()
~myObject()


Move Constructor called


Default Constructor called


Move Assignment called
~myObject()
~myObject()
~myObject()

似乎在myObject c = Getobject_Complex(1,0)行中,正在发生复制操作。但是据我了解,当禁用RVO并使用move操作定义对象时,应该调用move构造函数

为什么这里没有进行搬迁施工?我想念什么吗?

谢谢。

解决方法

似乎在myObject c = GetObject_Complex(1,0)行中,正在执行复制操作。

排序但不完全。更准确地说,复制操作发生在GetObject_Complex 三元条件运算符的结果被复制到临时返回值。

为什么这里没有进行搬迁建设?

没有move构造函数,因为编译器从函数调用的结果中消除了对移动的优化。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。