非可选指针与C ++中的非常量引用


12

其他C ++功能,参考参数的的谷歌C ++风格指南,我读的非const引用,不得使用。

通过引用传递的所有参数都必须标记为const。

很明显,对于C程序员来说,使用引用作为参数的函数调用绝对令人困惑,但是C和C ++现在是不同的语言。如果输出参数需要,使用指针为所需的输出参数,可能对被跳过整个功能体,这使得更复杂的功能(正式增加的实施圈复杂深度的函数的)。

我想使C ++代码尽可能容易理解/维护,因此我通常对阅读编码风格指南感兴趣。但是,为了适应团队中的最佳实践,我认为理解样式指导元素背后的原理是一个重要因素。

非常量引用真的那么糟糕吗?是只禁止Google禁止使用它们还是被普遍接受的规则?是什么证明了将输出参数实现为指针所付出的额外努力?


2
“使用指针会导致整个函数体被跳过”,那又是什么呢?
棘手怪胎2015年

@ratchetfreak我试图澄清这一点。我承认这样的功能可能会显示一些设计缺陷。指针在形式上始终是可选的,因此在取消引用之前必须对其进行检查。
狼”

4
Google的C ++样式指南倒退了。以我的主观意见,应该将其烧掉。
任思远

至于这个特殊的项目,我认为其理由是,当参数可能发生突变时,强迫程序员写一个“&”号就可以表现出更清晰的意图。
思源仁

4
Google样式指南的编写原封不动,以支持Google旧版项目中的同类代码。如果您不从事旧项目(从一开始就使用该样式指南编写),则可能不应该使用它(它指定了许多不利于新代码的规则(c ++ 11,c ++ 14) ,c ++ 17))。
utnapistim 2015年

Answers:


18

Google样式指南的基本原理只是从函数的调用站点中弄清楚参数是输入参数还是输出参数。(请参阅此处进行进一步的讨论。)其他语言通过设计明确显示出参数。例如,C#的out关键字必须在调用站点上使用。由于C ++并未明确指出,因此Google选择使用const ref。与指针,以使其清晰。

这只是Google的规定吗?不,但是我怀疑它是否广泛传播。我认为我没有在Google的风格指南和明确遵循Google风格指南的各个部分的小组之外看到它。(例如,几年前我第一次阅读Google样式指南并将其用于自己的一些代码时,我很喜欢这个想法。)

特别是,新发布的《C ++核心准则》更喜欢将返回值用于(几乎)所有内容的输出参数,而其余部分则使用非常量引用。Google对指针和引用的使用可能会使输出参数更清晰,但返回值仍然更清晰。既然C ++ 11具有标准化的移动(右值引用,&&以使许多类型的返回便宜)和元组(允许简单的方法返回多个值),则out参数的许多用例不再适用。

C ++核心准则背后有一些大人物(Bjarne Stroustrup,Herb Sutter),受到Microsoft的支持,并包含最新的C ++功能(与Google的风格指南不同),因此我希望它的建议会比Google的建议更受欢迎。


感谢您的回答(也感谢您对C#的简短介绍)。当然,轻松审查是重要的一点,尤其是在开源项目中。随着现代C ++的低回报,这些考虑将失去其重要性。对于较旧的旧版软件及其陈旧的编译器,它可能仍然很有帮助。

我没有忘记它,但是C ++核心准则并不那么快。有趣的是,它的“ 哲学”展示了规则背后的原理,并且还展示了一种现代化的编程观点(“直接在代码中表达思想”读起来有点像python的Zen),以此作为一种交流方式。

补充:直接链接到《 C ++代码准则》的“ 哲学”部分

1

有两种方法可以处理传入的无效指针:第一次检查和提早返回,或者使其成为未定义的行为(如果您更关心速度而不是健壮性)。

检查很简单:

void foo(void* buffer){
    if(buffer == nullptr)
        return;

    //actually foo

    // note no increase in indentation required

}

这种检查类型通常被接受为参数检查。如果您看到该代码,则很显然,您希望传入一个非null指针,如果没有,则提早返回。这使您不必担心无效的指针。


好吧,我考虑过这种模式,发现它绝对合理。遗憾的是,它看起来不像assert(buffer);知道assert仅在调试版本中处于活动状态那样清晰,有时我希望有一个rt_assert(buffer);引发异常的对象。缩进return看起来有些危险...顺便说一句:您的代码段很好地说明了我有关输出指针的问题。
2015年

1

这取决于您的观察If an output parameter is required

要求函数签名具有输出参数的唯一地方是外部API指定的地方,在这种情况下,您只需将外部API包装在确保始终有有效指针的对象中即可。

在内部,您可以通过将返回类型扩展为所有“输出”的组合来避免输出参数


您的意思是,我唯一无法提供非强制性指针的地方?是的,但是我不确定您的规则The only place where...是否真的适用于所有情况。您的建议如下所示:避免在自己程序的函数中使用输出参数。适用于新程序。
2015年

1
是的,请避免使用输出参数,而应使用复合返回类型,并对其进行编辑以使其更加清晰
Caleth,2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.