什么时候应该在 C++ 中使用引用?

2024-02-07

我已经编写 C++ 有一段时间了,我开始怀疑这个规则尽可能使用参考文献应该到处应用。

Unlike 这个相关的SO帖子 https://stackoverflow.com/questions/7058339/c-when-to-use-references-vs-pointers我对不同的事情感兴趣。

根据我的经验,引用/指针混合会弄乱您的代码:

std::vector<Foo *> &x = get_from_somewhere(); // OK? reference as return value
some_func_pass_by_ref(x); // OK reference argument and reference variable
some_func_by_pointer(x[4]); // OK pointer arg, pointer value
some_func_pass_elem_by_ref(*x[5]); // BAD: pointer value, reference argument
some_func_that_requires_vec_ptr(&x); // BAD: reference value, pointer argument

一种选择是更换& with * const like Foo & with Foo * const

void some_func_by_ref(const std::vector<Foo * const> * const); // BAD: verbose!

这样至少遍历就消失了。我重写函数头已经消失了,因为所有参数都将是指针......代价是污染代码const而不是指针算术(主要是& and *).

我想知道how and when你申请尽可能使用参考文献 rule.

考虑到:

  • 最小程度地重写函数原型(即:天哪,我需要重写很多原型,因为我想将此引用的元素放入容器中)
  • 增加可读性

    • 避免应用*转变Foo* to Foo&反之亦然
    • 避免过度使用 const,如* const

NOTES:我想到的一件事是,每当我打算将元素放入STL https://stackoverflow.com/questions/7707842/stl-containers-with-reference-to-objects容器(参见 boost::ref)

我不认为这是 C++03 特有的东西,但如果 C++11 解决方案可以向后移植到 C++03(即:NRVO 而不是 move-semantics),那么它们就很好。


什么时候应该在 C++ 中使用引用?

当您需要像对待对象本身一样对待变量时(大多数情况下,您不明确需要指针并且不想获得对象的所有权)。

我想知道您如何以及何时申请尽可能使用参考文献 rule.

只要有可能,除非你need to:

  • 处理地址(记录地址、诊断或编写自定义内存分配等)
  • 获取参数的所有权(按值传递)
  • 尊重需要指针的接口(C 互操作性代码和遗留代码)。

Bjarne Stroustrup 在他的书中指出,他引入了对该语言的引用,因为需要在不复制对象的情况下调用运算符(这意味着“通过指针”),并且他需要尊重类似于按值调用的语法(这意味着“不是通过指针”)(因此引用诞生了)。

简而言之,您应该尽可能少地使用指针:

  • 如果该值是可选的(“可以为空”),则在其周围使用 std::Optional,而不是指针
  • 如果您需要获得该值的所有权,请按值接收参数(而不是指针)
  • 如果您需要读取一个值而不修改它,请通过以下方式接收参数const &
  • 如果您需要动态分配或返回新/动态分配的对象,请通过以下方式之一传输值:std::shared_ptr, std::unique_ptr, your_raii_pointer_class_here- 不是通过(原始)指针
  • 如果您需要将指针传递给 C 代码,您仍然应该使用 std::xxx_ptr 类,并使用.get()用于获取原始指针。

我想到的一件事是,每当我打算将元素放入 STL 容器时就使用指针(或者我可以摆脱它吗?)

您可以使用Boost指针容器库 http://www.boost.org/doc/libs/1_54_0/libs/ptr_container/doc/ptr_container.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么时候应该在 C++ 中使用引用? 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • npm 警告可选跳过可选依赖项:[电子邮件受保护]

    我正在尝试使用 Angular CLI 安装 Angular 但当我尝试运行此命令时遇到错误 Command npm install g angular cli Error C Users abc gt npm install g angu
  • Makefile 动态变量作为先决条件

    也许这是我搞错了 基本上我的任务是使用make自动构建 部署 启动 停止不同的服务 我想做的事情之一是将变量作为目标先决条件 但是必须在另一个目标中更改该变量 这是我正在尝试做的事情的基本示例 IMAGE COUNT 1 count ima
  • ios7设备底部空间狭小

    我们正在开发一个适用于 ios6 和 ios7 的应用程序 我的问题是 如果我在设备中检查我的应用程序 则会发现一个小的空白区域 其大小等于屏幕底部状态栏的大小 如果我在屏幕顶部放置一个虚拟状态栏 它会在 ios6 中出现问题 如果您有任何
  • 如何将本地创建的函数和变量作为组件中的 props 传递?

    我有一个按钮组件 一个哑组件 我想附加一个可选的动画 并将该动画传递到 props 中 由另一个 prop 的布尔值触发 我在尝试同时通过这两个项目时不断遇到错误 Unknown prop ripple on
  • 确定 Mac 上 Java SDK 的版本

    我有一台运行 Snow Leopard 的 MacBook Pro 如何查看我的 Mac 上安装的 Java SDK 版本 打开终端并输入 java version or javac version 如果您拥有 Snow Leopard 的
  • 这是 Primefaces 错误还是 Mojarra/MyFaces 错误

    当我在里面时 我似乎无法触发事件column of dataTable 这是我的简单演示
  • Angular 7错误RangeError:超出最大调用堆栈大小

    我正在尝试通过以下方式学习角度官方教程 https angular io tutorial 但是当执行以下步骤时hero component and hero detail component 它会引发错误 RangeError 超出最大调
  • HQL:是否可以在子查询上执行 INNER JOIN?

    上图是我用来记录项目位置随时间变化的数据库结构的简化版本 我编写了以下 SQL 查询 该查询返回每个位置的当前商品库存 select from ItemLocationLog l inner join select g idItemLoca
  • 如何拥有 Active Admin 嵌套和非嵌套资源视图?

    一个用户有很多交易 我当前已将活动管理员设置为使用 admin transactions rb 中的 own to user 将事务嵌套在用户下以进行基本 CRUD 然而 我还需要一个事务的顶级视图 以显示跨用户的事务记录的子集 我怎样才能
  • 谷歌地图信息框 - maxWidth

    我面临谷歌地图信息框的奇怪行为 我将 maxWidth 调整为 0 以便让信息框大小根据内容进行调整 但我总是得到 236px 的信息框 var infobox new InfoBox maxWidth 0 pixelOffset new
  • 了解内存性能计数器

    更新 2010 年 9 月 30 日 由于我对此主题及相关主题进行了很多研究 因此我将写下我从此处答案中提供的经验和建议中收集到的任何提示 1 使用内存分析器 首先尝试使用 CLR Profiler 并找到消耗最大内存的例程并对其进行微调
  • 如何通过 xs:unique 使我的枚举变得唯一

    谁能指出为什么我的 XSD 中的独特元素没有强制唯一性 这应该会引发错误 因为最后一个ScreenResult元素不包含唯一值Type属性 我还应该指出 我确实在强迫其中一个之后Type within ScreenResults Scree
  • 类型错误:“未定义”不是函数(评估“$(文档)”)

    我正在使用 WordPress 网站 我将此脚本包含在标题中 当脚本加载时 我收到此错误 类型错误 未定义 不是函数 评估 文档 我不知道是什么原因造成的 甚至不知道它意味着什么 在萤火虫中 我得到这个 不是函数 WordPress 在中使
  • 如何去除所有换行符以生成正确的 CSV?

    我在正常工作的网站上有一个文本区域提交到我的数据库 但是当我从数据库生成 CSV 通过 PHP 时 所有换行符都会弄乱生成的 CSV 任何 CSV 阅读器都会将输入中的换行符解释为新行 我尝试过以下方法 将字段封装在引号中 This fie
  • oauth 中不支持的响应类型[重复]

    这个问题在这里已经有答案了 您好 我正在 Angular 2 中开发 Web 应用程序 我在 webapi 中有 oauth 身份验证 我在前端使用 Angular 2 登录时我调用下面的代码 private login this oaut
  • << 具有多个参数的运算符[重复]

    这个问题在这里已经有答案了 我只是想知道我们是否可以为运算符 举个例子会更明确 anyType operator lt lt arg p1 arg p2 DoSomethingWith p1 DoSomethingWith p2 retur
  • OpenCV Python 错误断言失败(scn == 3 || scn == 4)

    我刚刚开始玩OpenCV在 Python 中 我遇到了断言错误 我从a复制了以下代码tutorial http docs opencv org trunk doc py tutorials py gui py video display p
  • MySQL 中“FOR XML AUTO”的等效项是什么? (用于具有代表行的 XML 字符串)

    在 SQL Server 中 我经常使用 FOR XML AUTO 它允许 SELECT id FROM car FOR XML AUTO 返回 12 MySQL 有没有办法做到这一点 我想要的是能够将此 XML 存储在另一个表中 这样我就
  • 将 Z 轴与向量对齐的最简单方法是什么?

    给定一个点 如 0 0 0 和一个向量 如 x y z 对齐以 0 0 0 为中心的负 Z 轴以指向该向量的方向的最简单方法是什么 使用 OpenGL 的示例将受到欢迎 但不是必需的 有很多不同的方法可以旋转坐标系以指向给定方向 它们都会使
  • 什么时候应该在 C++ 中使用引用?

    我已经编写 C 有一段时间了 我开始怀疑这个规则尽可能使用参考文献应该到处应用 Unlike 这个相关的SO帖子 https stackoverflow com questions 7058339 c when to use referen