移动语义机制 我已经开始学习C++,但是我对移动语义有一些怀疑。当书中说A的move构造函数“窃取”右值B的属性时,是不是意味着指向V值的指针从B切换到A?这样,A就不需要分配另一部分内存了

移动语义机制 我已经开始学习C++,但是我对移动语义有一些怀疑。当书中说A的move构造函数“窃取”右值B的属性时,是不是意味着指向V值的指针从B切换到A?这样,A就不需要分配另一部分内存了,c++,move-semantics,C++,Move Semantics,如果是的话,为什么在这个代码中 class CBuffer{ private: int size; int csize; char* ptr; char rtp; public: CBuffer(int size): size(size), csize(0){ ptr = new char[size]; *ptr = 'a'; } CBuffer(const CBuffer& source): si

如果是的话,为什么在这个代码中

class CBuffer{
private:
    int size;
    int csize;
    char* ptr;
    char rtp;
public:
    CBuffer(int size): size(size), csize(0){
        ptr = new char[size];
        *ptr = 'a';
    }

    CBuffer(const CBuffer& source): size(3), csize(source.csize) {
        this->ptr = new char[size];
        memcpy(this->ptr, source.ptr, size);
    }

    CBuffer(CBuffer&& source){
        this->ptr = source.ptr;
        this->size = source.size;
        std::cout << &this->ptr << std::endl;
        std::cout << &source.ptr << std::endl;
        source.ptr = nullptr;
    }

};



int main(){
    CBuffer a = CBuffer(1);
    CBuffer b = std::move(a);
    CBuffer c = b;
类CBuffer{
私人:
整数大小;
int csize;
char*ptr;
字符rtp;
公众:
CBuffer(int size):大小(size),csize(0){
ptr=新字符[大小];
*ptr='a';
}
CBuffer(constcbuffer&source):大小(3),csize(source.csize){
此->ptr=新字符[大小];
memcpy(this->ptr,source.ptr,size);
}
CBuffer(CBuffer&源){
此->ptr=source.ptr;
此->大小=source.size;

move语义意味着,我们不创建另一个对象的副本,而是允许该对象获取该另一个对象内部任何动态分配的内存

我们通过在两者之间交换任何动态分配的内存来实现这一点,这意味着(这意味着存储在指针中的内存地址)第一个对象中指针的值现在将是新对象中指针的,我们在右值引用中放置了一个null ptr,因此当它被销毁时,它也会销毁它

我在代码中添加了一些内容:

  • 我已经初始化了初始值设定项列表中的所有变量。此外,我还删除了副本中大小的硬编码初始化
  • 在复制/移动操作中,通常为其他对象使用“其他”名称
  • 一个错误:您必须在ptr中放入一个值,不初始化变量是一种不好的做法。实际上,如果我们添加一个dtor,并在此处使用交换习惯用法(解释如下),则会导致无效的删除
  • 最后但并非最不重要的一点是,可以对活动对象调用move-ctor,而不是删除当前ptr,而是将nullptr放在其他ptr上,这意味着永远不会删除该ptr。例如,如果main是:
  • 交换成语对我们有什么帮助

    让我们看一看我的例子;当我们交换值(意思是
    a.ptr=old b.ptr
    b.ptr=old a.ptr
    )时,每当b被删除时,现在驻留在b中的“old”a.ptr就会被删除,因为我们只是交换了它们。通常,当我们使用移动语义时,rvalue很快就会被破坏,我们只是“骑”对其进行销毁,以防止内存泄漏

    您的代码应该是这样的(添加了一些打印以便更好地理解):


    它打印的是指针的地址,而不是指针的值。
    &this->ptr
    &source.ptr
    是指针的地址变量。而不是指针指向的对象的地址。当它从B“偷走”内存时,为什么需要分配更多内存?那太贪婪了。我认为
    source
    或者
    src
    也是一个非常常见的名称,实际上描述了它的含义。我只遇到过其他名称,在中也是这样。总之,我对自己说,有些使用源代码。
    std::cout << &this->ptr << std::endl;
    std::cout << &source.ptr << std::endl;
    
    int main()
    {
        CBuffer a{1};
        CBuffer b{2};
        a = std::move(b); // legal, but causes memory leak in your code, the value of a.ptr is never deleted!
    }
    
    class CBuffer{
    private:
        int size = 0;
        int csize = 0;
        char* ptr = nullptr; // very important!!!
        char rtp = 0;
        int id = 0;
    
    public:
        static int get_current_count() 
        { 
            static int object_cnt = 1;
            return object_cnt++; 
        }
    
        CBuffer(int size) : 
            size(size), 
            csize(0),
            ptr(new char[size]),
            rtp(0)
        {
            id = get_current_count();
            std::cout << "On ctor of " << id << std::endl;
            ptr[0] = 'a';
        }
    
        CBuffer(const CBuffer& other) : 
            size(other.size), 
            csize(other.csize), 
            ptr(new char[size]),
            id(get_current_count())
        {
            std::cout << "On copy ctor of " << other.id << " to " << this->id << std::endl;
            std::memcpy(this->ptr, other.ptr, size);
        }
    
        CBuffer(CBuffer&& other) :
            size(other.size),
            csize(other.csize),
            rtp(other.rtp), 
            id(get_current_count())
        {
            std::cout << "On move ctor of " << other.id << " to " << this->id << std::endl;
            std::swap(this->ptr, other.ptr);
        }
    
        ~CBuffer()
        {
            std::cout << "On dtor of " << id << std::endl;
            delete[] ptr;
        }
    };
    
    int main()
    {
        CBuffer a = CBuffer(1);
        CBuffer b = std::move(a);
        CBuffer c = b;
    }
    
    On ctor of 1
    On move ctor of 1 to 2
    On copy ctor of 2 to 3
    On dtor of 3
    On dtor of 2
    On dtor of 1