草庐IT

C++ 右值引用与一级指针

木三百川 2023-04-17 原文

右值引用用于一级指针,在初始化时等号右边必须为右值,有以下几种用法:

//方式一:引用一级指针,常规用法
int a = 5;
int * &&rrpa = &a;       //右值:例子一
int * getPx() { return new int; }
int * &&rrpa = getPx();  //右值:例子二
int * pa = &a;
int * &&rrpa = std::move(pa);//右值:例子三

//方式二:引用指向常量的一级指针,以下几种为等效表示
int a = 5;
const int * &&rrpac = &a; //方式一
int const * &&rrpac = &a; //方式二

//方式三:引用一级指针的常引用,引用自身为常量
int a = 5;
int * const &&crrpa = &a;

//方式四:引用指向常量的一级指针,且引用自身为常量,以下几种为等效表示
int a = 5;
const int * const &&crrpac = &a; //方式一
int const * const &&crrpac = &a; //方式二

Microsoft Visual Studio 中连续多个 const 会被编译器解释成一个,即 const const const const int *&&const int *&& 等效,除此之外,const int const *&&Microsoft Visual Studio 中也与 const int *&& 等效,而 int *&& constQT minGW 中将会报错,在 Microsoft Visual Studio 中与 int *&& 等效。

各类型引用可修改属性如下表所示:

引用类型 修改 *rrp 修改 rrp
int * &&rrp 可以 可以
const int * &&rrp 不可以 可以
int * const &&rrp 可以 不可以
const int * const &&rrp 不可以 不可以

若将变量的地址赋予引用(例如 rrp=&x),各类型引用可接受的变量地址如下表所示:

引用类型 int变量地址 const int变量地址
int * &&rrp 可以 不可以
const int * &&rrp 可以 可以
int * const &&rrp 声明时可以 不可以
const int * const &&rrp 声明时可以 声明时可以

若将函数返回的一级指针值赋予引用(例如 rrp=getPx()),或者使用形如 rrp=(const int *) &x 的强制类型转换,此时各类型引用可接受的类型如下表所示:

引用类型 int * const int * int * const const int * const
int * &&rrp 可以 不可以 可以 不可以
const int * &&rrp 可以 可以 可以 可以
int * const &&rrp 声明时可以 不可以 声明时可以 不可以
const int * const &&rrp 声明时可以 声明时可以 声明时可以 声明时可以

由于右值引用变量自身为左值,因此不能直接将右值引用变量的值赋予另一个右值引用变量,但可以将函数返回的右值引用值赋予另一个右值引用变量(例如 rrp=getRRPx()),也可以使用 std::move() 将左值转换为右值(例如 rrp=std::move(px)),此时各类型引用可接受的类型如下表所示。比较上下两表可知,它们的差别主要在于最后两列,这是因为 int * constconst int * const 中右边的 const 修饰的是一级指针自身,而 int * const &&const int * const && 中右边的 const 修饰的是右值引用自身,代表的含义不同。

引用类型 int * && const int * && int * const && const int * const &&
int * &&rrp 可以 不可以 不可以 不可以
const int * &&rrp 可以 可以 不可以 不可以
int * const &&rrp 声明时可以 不可以 声明时可以 不可以
const int * const &&rrp 声明时可以 声明时可以 声明时可以 声明时可以

右值引用在声明时是否会创建临时变量,这与具体应用场景有关,可在编译后查看对应的汇编代码,也可参考本人另一篇博客 C++ 右值引用与 const 关键字。关于左值引用与一级指针,可参考本人另一篇博客 C++ 左值引用与一级指针

有关C++ 右值引用与一级指针的更多相关文章

  1. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  2. ruby - Chef LW 资源属性默认值如何引用另一个属性? - 2

    我正在尝试将一个资源属性的默认值设置为另一个属性的值。我正在为我正在构建的tomcat说明书定义一个资源,其中包含以下定义。我想要可以独立设置的“名称”和“服务名称”属性。当未设置服务名称时,我希望它默认为为“名称”提供的任何内容。以下不符合我的预期:attribute:name,:kind_of=>String,:required=>true,:name_attribute=>trueattribute:service_name,:kind_of=>String,:default=>:name注意第二行末尾的“:default=>:name”。当我在Recipe的新block中引用我

  3. ruby - 在 Ruby 中,为什么 Array.new(size, object) 创建一个由对同一对象的多个引用组成的数组? - 2

    如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta

  4. ruby - 引用具有指定索引的枚举器值 - 2

    假设我有一个可枚举对象enum,现在我想获取第三个项目。我知道一种通用方法是转换成数组,然后使用索引访问,如:enum.to_a[2]但这种方式会创建一个临时数组,效率可能很低。现在我使用:enum.each_with_index{|v,i|breakvifi==2}但这非常丑陋和多余。执行此操作最有效的方法是什么? 最佳答案 你可以使用take剥离前三个元素,然后剥离last从take给你的数组中获取第三个元素:third=enum.take(3).last如果您根本不想生成任何数组,那么也许:#Ifenumisn'tanEnum

  5. ruby 变量作为同一对象(指针?) - 2

    >>a=5=>5>>b=a=>5>>b=4=>4>>a=>5如何将“b”设置为实际的“a”,以便在示例中,变量a也将变为4。谢谢。 最佳答案 classRefdefinitializeval@val=valendattr_accessor:valdefto_s@val.to_sendenda=Ref.new(4)b=aputsa#=>4putsb#=>4a.val=5putsa#=>5putsb#=>5当您执行b=a时,b指向与a相同的对象(它们具有相同的object_id).当你执行a=some_other_thing时,a将指向

  6. ruby - 在多个线程中引用类方法会导致自动加载循环依赖崩溃 - 2

    代码:threads=[]Thread.abort_on_exception=truebegin#throwexceptionsinthreadssowecanseethemthreadseputs"EXCEPTION:#{e.inspect}"puts"MESSAGE:#{e.message}"end崩溃:.rvm/gems/ruby-2.1.3@req/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:478:inload_missing_constant':自动加载常量MyClass时检测到循环依赖稍加研究后,

  7. Ruby 泄露的对象被 RubyVm::Env 引用 - 2

    我正在跟踪我们的应用程序(ruby2.1)中的内存泄漏问题。我正在使用这两种技术:ObjectSpace.dump_all将所有对象转储到JSON流,然后进行离线分析。我使用的第二种技术是使用ObjectSpace.reachable_objects_from进行实时分析。在这两种方式中,我发现我泄漏的对象被一个对象RubyVM::Env引用。任何人都可以向我解释什么是RubyVM::Env。如何删除这些引用? 最佳答案 RubyVM::Env是一个包含变量引用的内部ruby​​类。这是我的测试:require'objspace'a

  8. ruby - 方法如何引用运算符。 : work? - 2

    这个问题不是很有用因为themethodreferenceoperatorwasremovedfromRuby2.7.0发布前。由于历史原因,这个问题被搁置了。Ruby2.7.0-preview1引入了方法引用运算符.:作为实验性功能。(更多here和here)。有一些抽象示例可用于说明如何使用这个新运算符:method=42.:to_s=>#method.receiver=>42method.name=>:to_smethod.call=>"42"和:method=File.:read=>#method.call('/Users/foo/.zshrc')=>"exportZSH=$H

  9. ruby 认为我在引用一个顶级常量,即使我指定了完整的命名空间 - 2

    在我的应用程序中我有classUserincludeUser::FooendUser::Foo定义在app/models/user/foo.rb现在我正在使用一个定义了自己的Foo类的库。我收到此错误:warning:toplevelconstantFooreferencedbyUser::FooUser仅引用具有完整路径的Foo,User::Foo,而Foo实际上从来没有指的是Foo。这是怎么回事?更新:才想起我之前遇到过同样的问题,在问题1中看到这里:HowdoIrefertoasubmodule's"fullpath"inruby? 最佳答案

  10. ruby - 维基引用API? - 2

    我想通过JSON获取Wikiquote页面的结构化版本(基本上我需要所有短语)示例:http://en.wikiquote.org/wiki/Fight_Club_(film)我试过:http://en.wikiquote.org/w/api.php?format=xml&action=parse&page=Fight_Club_(film)&prop=text但我得到了所有HTML源代码。我需要每个pharse作为数组的一个元素我如何使用DBPEDIA实现这一目标? 最佳答案 首先,我不确定您是否可以使用DBpedia查询wiki

随机推荐