自学内容网 自学内容网

2411d,右值与移动

原文

概述

添加语言内部__rvalue(Expression)函数,指示对匹配函数参数,按右值对待.这在用非引用语义调用函数时启用移动语义.

移动语义运行时和资源效率可取的,因为可移动资源新对象,而不是复制然后析构.其他语言(如C++)有流行移动语义.

先前的工作

C++移动语义这里
RustC++移动语义对比这里
C++语义有害(Rust更好)这里

描述

语法

RvalueExpression是个附加PrimaryExpression:

RvalueExpression:
    __rvalue ( AssignExpression )

重载

如果同时有引用非引用参数重载,则偏爱匹配右值非引用参数,而偏爱左值引用参数匹配.RvalueExpression最好与非引用参数匹配.

右值参数匹配参数语义

调用函数拥有对待右值参数.因此,如果左值与右值参数匹配,则会给函数传递左值副本.然后,在函数结束时该函数对(如果有)参数调用析构器.

不会复制右值参数,因为按唯一假设它,且在函数结束时也会析构它.编译器会自动函数体附加析构.

函数无法知道其参数源右值还是左值的副本.

即在函数返回时,__rvalue(左值式)参数析构式.不能继续使用左值式.在传递给函数后,编译器并不总是可检测到使用,即对象的析构器必须按其初值或至少是良性值,重置对象的内容.

struct S
{
    ubyte* p;
    ~this()
    {
      free(p);
      //在此添加:`'p=null;'`
    }
}
void aggh(S s)
{
}
void oops()
{
    S s;
    s.p = cast(ubyte*)malloc(10);
    aggh(__rvalue(s));
    free(s.p); //错误,两次释放`s.p`
}

__rvalue移动赋值

struct S
{
    ubyte* p;
    ~this()
    {
      free(p);
      p = null;
    }
    void opAssign(S s)
    {
        this.p = s.p;
        s.p = null;
    }
}
void oops()
{
    S s;
    s.p = cast(ubyte*)malloc(10);
    S t;
    t = __rvalue(s);
}

__rvalue移动构造

struct S
{
    ubyte* p;
    ~this()
    {
      free(p);
      p = null;
    }
    this(S s)
    {
        this.p = s.p;
        s.p = null;
    }
}
void oops()
{
    S s;
    S t = __rvalue(s);
}

原文地址:https://blog.csdn.net/fqbqrr/article/details/143661334

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!