当前位置:  开发笔记 > 编程语言 > 正文

指针与参考

如何解决《指针与参考》经验,为你挑选了5个好方法。

在给函数提供原始变量时,最好的做法是:

unsigned long x = 4;

void func1(unsigned long& val) {
     val = 5;            
}
func1(x);

要么:

void func2(unsigned long* val) {
     *val = 5;
}
func2(&x);

IOW:有没有理由选择一个而不是另一个?



1> Nils Pipenbr..:

我的经验法则是:

如果你想用它们做指针运算(例如递增指针地址以逐步遍历数组)或者你必须传递一个NULL指针,请使用指针.

否则使用参考.


用算术解释你的意思.新用户可能无法理解您要调整指针指向的内容.
关于指针为NULL的优点.如果你有一个指针参数,那么你必须明确检查它是不是NULL,或者搜索函数的所有用法以确保它永远不是NULL.参考不需要这种努力.
马丁,通过算术我的意思是你传递一个指向结构的指针,但知道它不是一个简单的结构,而是一个数组.在这种情况下,您可以使用[]对其进行索引,或者在指针上使用++/ - 进行算术运算.简而言之,这就是区别.
马丁,你只能用指针直接做到这一点.没有参考.当然你可以把一个指针指向一个引用并在实践中做同样的事情,但如果你这样做,你会以非常脏的代码结束.

2> Johann Gerel..:

我真的认为你将从建立以下函数调用编码指南中受益:

    和所有其他地方一样,总是const正确的.

    注意:这意味着,除其他外,只有out-values(参见第3项)和value传递的值(参见第4项)可能缺少说明const符.

    如果值0/NULL是当前上下文中的有效输入,则仅通过指针传递值.

    理由1:作为调用者,您会看到无论您传入的是什么,都必须处于可用状态.

    理由2:由于,你知道,无论发生什么事的处于可用状态.因此,不需要对该值进行NULL检查或错误处理.

    基本原理3:基础知识1和2将被编译器强制执行.如果可以的话,总是在编译时捕获错误.

    如果函数参数是out-value,则通过引用传递它.

    理由:我们不想打破第2项......

    只有当值是POD(普通旧数据结构)或足够小(内存方式)或以其他方式足够便宜(按时间)复制时,选择"按值传递"而不是"传递const引用" .

    理由:避免不必要的副本.

    注:足够小足够便宜,都不是绝对的衡量标准.



3> Aaron N. Tub..:

这最终成为主观的.到目前为止的讨论很有用,但我认为没有正确或果断的答案.很多将取决于风格指南和您当时的需求.

虽然使用指针有一些不同的功能(无论是否可以为NULL),但输出参数的最大实际差异纯粹是语法.例如,谷歌的C++风格指南(https://google.github.io/styleguide/cppguide.html#Reference_Arguments)只强制指针输出参数,并且只允许引用为const.推理是可读性:具有值语法的东西不应该具有指针语义.我并不是说这必然是对或错,但我认为这里的重点是风格,而不是正确性.



4> Max Caceres..:

如果要修改变量的值,则应传递指针.即使技术上传递引用或指针是相同的,在您的用例中传递指针更具可读性,因为它"通告"该值将由函数更改的事实.


@AlexanderKondratskiy:你错过了这一点......你无法立即看到*在调用站点*被调用的函数是否接受一个参数作为`const`或非`constst`引用,但你可以看到参数传递了al​​a`&x`与`x`,并使用该对流来编码参数是否易于修改.(也就是说,有时候你会想要传递一个`const`指针,所以对象只是一个暗示.可疑的东西可能会被修改,当它不会被认为不那么危险而不是认为它不会是什么时候这将是....)
如果你遵循Johann Gerell指南,非const引用也会公布一个可变变量,所以指针在这里没有这个优势.

5> 小智..:

如果您有一个参数,您可能需要指示缺少值,通常的做法是使参数成为指针值并传入NULL.

在大多数情况下(从安全角度来看)更好的解决方案是使用boost :: optional.这允许您通过引用传递可选值,也可以作为返回值.

// Sample method using optional as input parameter
void PrintOptional(const boost::optional& optional_str)
{
    if (optional_str)
    {
       cout << *optional_str << std::endl;
    }
    else
    {
       cout << "(no string)" << std::endl;
    }
}

// Sample method using optional as return value
boost::optional ReturnOptional(bool return_nothing)
{
    if (return_nothing)
    {
       return boost::optional();
    }

    return boost::optional(42);
}

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有