可读性是在(参考)参数中不使用const的正当理由吗?


24

在编写一些函数时,我在这样的参数中找到了const关键字:

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
}

通常会导致在IDE或vim中将一行分成两行,因此我想删除参数中的所有const关键字:

void MyClass::myFunction(MyObject& obj,string& s1,string& s2,string& s3){
} 

这是不使用const的正当理由吗?手动保持参数对象不变是否可以维护?


110
“嘿,我想在功能上更改程序”以使其更具可读性,这是一个不好的坏理由。
Pieter B

37
无论如何,该程序都不会变得更具可读性-一旦您看到有东西要移交,就const可以有一个很强的暗示,那就是您不需要理会如何在函数中进行更改。
tofro

43
提高可读性的更好方法是减少参数数量
5gon12eder

15
“ const”无疑可以提高可读性。该语句明确表明obj可能不会更改!
查尔斯

14
帮助可读性的是在每个逗号后添加一个空格。
sam hocevar '16

Answers:


182

可读性是学习使用空格的有效理由:

void MyClass::myFunction(
        const MyObject& obj,
        const string& s1,
        const string& s2,
        const string& s3
) {
    return;
}

位于那儿的参数不会与函数的主体混淆。通过将它们定位在不同的行上,当您将其名称更改为myFunction更具描述性的名称时,您无需重新定位它们。当用户未更改参数位置时,不更改它们的位置是源代码控制差异工具用户会喜欢的。

const意味着什么。不要仅仅因为您没有空间和想法而把它扔掉。可读性为王,但以它的名义破坏事物只是放弃。


6
“更改myFunction的名称时,您不必重新定位它们” –尽管在这种情况下,看起来好像它们的位置与开口大致对齐(,如果是这样,则可能必须重新定位如果类名+函数名的长度变化超过4个字符,则使用它们。因此,如果不想这样做,请添加固定数量的缩进级别,而不是取决于函数名称长度的数量。我建议使用1级,此答案使用6,但是任何固定的数字均会达到所述目标:-)
史蒂夫·杰索普

6
@CandiedOrange我很惊讶您在此答案中没有使用“ form 6”…… 显然不那么丑陋!
svidgen

6
中奖形式6。一层缩进的一个制表符空间。简单有效。解决的问题:)
莫妮卡(Monica)

2
好吧,好的表格6。这是JeffGrigg在c2上提到的变体。
candied_orange

4
@ random832我认为我们现在已经牢牢地扎在自行车棚领域。解决此问题的正确方法是:在代码库中搜索示例,咨询商店风格指南,询问商店中的开发人员,如果这些都不产生权威性的答案,请使用此方法。解决可能四分之一的纠纷。季度发言后要保持一致!
candied_orange

52

实际上,可读性问题肯定是另一个方向。首先,您可以使用空白简单地解决您的生产线。但是删除const不仅会缩短行,而且会完全改变程序的含义。

Herb Sutter将const引用const称为最重要,const因为对的引用const可以绑定到临时对象并延长其寿命。对非const不能的左值引用,您需要一个单独的变量。

void foo_const(std::string const& );
void foo_nc(std::string& );

std::string some_getter();

foo_const(some_getter());      // OK
foo_const("Hello there"); // OK

foo_nc(some_getter()); // error
foo_nc("Nope");   // error

std::string x = some_getter(); // have to do this
foo_nc(x);                     // ok
std::string msg = "Really??";  // and this
foo_nc(msg);                   // ok

这对可用性意味着意味着您将必须引入所有这些临时变量才能调用您的函数。这对可读性不是很好,因为这些变量是无意义的,仅因为您的签名错误而存在。


6
您的第二段让我很头疼,想弄清楚const是在const指的是对方constconst还是最重要的是const
-Mindwin

3
@Mindwin我认为具有讽刺意味的是,我的第二段内容清晰明确,我不知道你在说什么。
巴里2016年

2
@Barry无疑是明确的,但是我花了一些时间对该段内容进行了尝试才能弄清楚它的含义。我认为有些麻烦是可以将其解析为“ Herb Sutter将const(引用const)称为最重要的const ...”或“ Herb Sutter将const(引用const)视为最重要的const ...”。重要的常量...”,我相信后者是单词的唯一有效分组,但是要花一些时间来处理它。也许有一种使用引号消除歧义的方法?
Cort Ammon-恢复莫妮卡

1
我认为某些连带的化合物会清除这种情况。
shawnt00

2
或专门使用const&而不是引用那里const的名词
Caleth,2016年

21

简单的答案是“否”。

长的答案是const关键字是功能提供的合同的一部分;它告诉您参数将不会被修改。删除const保证的那一刻消失了。请记住,您不能使用文档,约定或准则来合理地维护某些事物的常数(或其他属性)-如果该常数不是由编译器强制执行的,则有人认为,如果他们精疲力竭,可以使工作变得更轻松参数“只是一点”。考虑:

// parameter "foo" is not modified
void fna(Foo& foo);

void fnb(const Foo& foo);

除了后者的版本更简洁外,它还提供了更强大的协定,并允许编译器帮助您保持意图。前者没有采取任何措施来防止该fna(Foo&)函数修改您传递给它的参数。

就像在@CandiedOrange答案中一样,您可以使用空格布置代码并增强可读性。


14

删除const关键字会降低可读性,因为它会将const信息传达给阅读器和编译器。
减少代码的水平长度是很好的(没人喜欢横向滚动),但是const除了文本之外,还有很多其他内容。您可以重写它:

typedef string str;
typedef MyObject MObj;
void MyClass::myFunction(const MObj& o,const str& s1,const str& s2,const str& s3)

这不会改变合同,但可以满足减少线长的需求。确实,我认为上面的代码片段可读性较低,并且会选择使用更多的空格,正如CandiedOrange的答案中已经提到的那样。

const是代码本身的功能。您不会将函数设为非成员来删除MyClass::声明的这一节,所以请不要删除const


4
我同意您提供的代码片段可读性较差。它迫使读者去找出MObjstr是的,肯定让人大跌眼镜。这是该类型的名称,你已经可以控制特别怪异:比如你为什么不只是名称MyObjectMObj使用开始?
杰森C

3

可读性是在参数中不使用const的正当理由吗?

否。省略const会改变功能,失去const提供的保护,并可能创建效率较低的代码。

手动保持参数对象不变是否可以维护?

而不是花时间手动设置代码格式

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
  //
}

使用自动格式化工具。根据功能要求编写功能,并让自动格式化处理演示文稿。手动调整格式的效率不如使用自动格式并节省时间来改进代码的其他方面。

void MyClass::myFunction(const MyObject& obj, const string& s1, const string& s2, 
    const string& s3) {
  // 
}

-1

只要有可能,最好使const保持可见。它极大地改善了代码维护(不要猜测此方法是否会更改我的参数)。

如果我在一个方法中看到很多参数,这将迫使我考虑创建基于项目的jaron(矩阵,雇员,矩形,客户),该jaron会更短,更易于理解(消除了方法的一长串参数)。


同意 我很犹豫地指出这一点。因此,“极端情况”。
blackpen

@cmaster那就是说,有时在某些情况下,某些程序员保持可读性。例如,在非常特殊的Windows API调用程序中,对于习惯于这种环境的读者来说,例如typedef Point * LPPOINT和和之类的东西typedef const Point * LPCPOINT虽然令人讨厌,但仍带有隐含含义,因为它与即时期望相符。在上下文中。但一般情况下绝不会;我能想到的只是一个奇怪的例外。
杰森C

1
是的,当我看到“ const unsigned long long int”这个问题时,我就想到了,但是从“ const”或“ reference”中获取收益并不是一个很好的选择。typedef解决了缩短名称的一般问题;但是将语言构造(例如“ const”)的真正目的隐藏在它的后面并不是很好的设计。
blackpen
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.