关于向c++例程传递参数时使用指针/引用的建议
Advice on the use of pointers/references when passing arguments to C++ routines
我在嵌入式环境(实际上是c++的一个子集)中使用c++,并且想要一些关于在向例程传递参数时使用指针/引用的建议。
一个常见的技巧是"尽可能使用引用,必要时使用指针"。我相信这与避免空指针有关。但是,当前的编程指南禁止使用引用。
请参考下面的讨论,看看你是否同意。
伯特:我们应该在适当的时候利用引用传递参数(内置空指针保护)。这将产生更小、更健壮的代码。
厄尼:我不同意。使用引用隐藏了可能被更改的参数,因此,当您检查代码或查看特定函数正在做什么时,您现在必须查看它调用的每个函数,以及它们调用的每个函数,以查看您传入的任何参数是否可能被更改。然而,如果你使用指针,那么你知道如果你传入一个指针,它可能会被改变。如果你没有传递一个指针,那么你就知道它没有被改变。这种易于维护的特性值得解决NULL指针问题。对于引用,仅仅因为你没有NULL指针问题,并不意味着对象已经被正确初始化,并且你有良好的数据。
伯特:可以通过将输入参数(引用)标记为"const"来减轻这种担忧。(这类似于Google的编码风格。)那么您就知道其他参数是可以修改的。可修改的参数可以以"r"开头,这在前面的指导方针中是允许的。(当Visual Assist等工具对输入/输出进行颜色编码以帮助提供视觉提示时,不要感到惊讶。)
厄尼:将参数(引用)标记为"const"并不能缓解这个问题。因为当你在一个层次上有人在调用这个函数时,你只有一个常规变量,比如nSomeNumber。你必须去函数原型看看变量是否可能被改变。或者,你必须将鼠标悬停在函数上才能看到原型。所以你不能只是快速扫一扫代码就知道可能会发生什么。此外,有些时候你没有颜色编码,比如在代码审查期间的Beyond Compare中,你不能轻松地悬停或转到原型。我强烈反对使用引用,因为它们使代码的维护和可读性变得困难,而且容易出错;你得到的错误不是简单的检测NULL指针问题,它们是逻辑错误,其中一个值被设置在函数之上并作为引用传递给函数,然后在函数被调用后使用该值,而不是期望它改变。
Grover:仅供参考,Google允许const引用作为参数。据推测,这是为了节省复制对象的成本。Google不允许简单引用参数。如果要更改对象,则通过指针传递它。http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments
一个常见的技巧是"尽可能使用引用,必要时使用指针"。我相信这与避免空指针有关。
这是一个很好的建议,是的,避免空指针是原因(它也更容易阅读,因为你不需要不断取消引用,或使用->
)
Grover:仅供参考,Google允许const引用作为参数。据推测,这是为了节省复制对象的成本。Google不允许简单引用参数。如果要更改对象,则通过指针传递它。
我可以理解反对使用非const引用的理由。在这种情况下,Google的风格指南是最好的方法(输入使用const引用,输出使用指针)。不使用const引用作为输入简直是疯了:你要么必须按值传递,这将非常慢,要么通过指针传递,这将需要大量的地址获取和解引用(更不用说无意义的空指针检查)。这个会使代码更加难以读懂,而不是担心修改的引用。
我的建议是引用总是const
(像谷歌风格),除非从函数的任务中可以明显看出参数最终可能在函数内部被修改。在我看来,这应该只发生在所有其他方式都不那么可读的时候,也就是说,你通常应该尽可能地保持函数的"功能性",接受const参数并返回其他东西。这取决于c++的这个子集有多大,这应该不是一个问题:你可能会试图在一个函数f
中改变的可变状态信息几乎总是可以以一种方式组织,使这个信息驻留在f
是成员的c
类中,然后你可以进一步分离"修改函数"answers"纯函数",这样你的函数最终大多是这两种形式
class c;
ret_T f0(const arg1T &, const arg2T &, ...);
ret_T c::f1(const arg1T &, const arg2T &, ...) const; // pure functions
void c::f3(const arg1T &, const arg2T &, ...); // modifying functions
c &c::f2(const arg1T &, const arg2T &, ...){
... return *this;
}
显然,这并不总是可能的,或者至少不是总是可行的,但它经常是,所以给那些不适合这种模式的函数(即返回一些重要的和修改状态的函数)一个漂亮的长描述性名称不会有什么伤害,以清楚地表明它们会。
- 如何使用基类指针引用派生类成员
- 将常量指针引用绑定到非常量指针
- 如果非动态变量被指针引用,何时超出范围?
- 转换指针引用的字符串
- 指针引用的生存期(以 C++为单位)
- 从 unique_ptr::get 发送指针作为指针引用进入函数
- 指针/引用的 CLion 格式
- 使用模板专用化来比较指针引用
- 如何保存指向抽象基类的指针/引用,但在 c++ 中仍然可以复制
- C++初始化指针/引用/复制细微差别
- 用数组或指针引用函数?
- 指针范围问题和返回类中封装的指针向量内的指针引用
- 强制转换为指针引用是否会导致未定义的行为
- 访问由 void 指针引用的结构的成员
- C 为什么当先前的步骤引发异常时,std :: shared_ptr的指针引用会被破坏
- 动态指针引用数组由三元运算符返回值,但有异常
- 悬空指向 int 和 char* 常量的指针/引用
- C++ 二维数组和指针引用
- 通过使用指针/引用,在C++中使用向量加快计算速度
- C++非类型模板模板到函数指针/引用