带有基本类型的c++ const修饰符

C++ const modifier with primitive types

本文关键字:const c++ 类型      更新时间:2023-10-16

我应该注意const修饰符与基本类型的工作吗?哪一个在语法上更正确,为什么?

第一个版本:

float Foo::bar(float a, float b)
{
    return (a + b) / 2.0f;
}

第二次版本:

const float Foo::bar(const float a, const float b)
{
    return (a + b) / 2.0f;
}
第三版:

float Foo::bar(const float a, const float b)
{
    return (a + b) / 2.0f;
}

我知道原始类型的变量在传递给某些方法时被复制,但哪种方式更清楚?

我认为第三个版本是最"正确"的。

你告诉编译器参数是const,这是正确的,因为你没有修改它们。这可以帮助编译器优化参数的传递和计算。

返回类型不是const,因为调用者可能想要修改返回值。如果调用者不想修改返回值,则由调用者将其分配给const变量。

我还会将const添加到函数声明中,因为该函数不会修改对象中的任何内容:

float Foo::bar(const float a, const float b) const

由于该函数不访问对象的任何成员,那么我也将其设为static

首先,您提供的所有定义语法正确。如果它们可以编译,那么它们的语法是正确的。

形参上的const限定符只有一个目的:防止函数体修改const限定实参。

在您的示例代码的特定情况下,Foo::bar方法不修改参数,因此使用const限定符没有任何影响。

但是,您可能希望在所有情况下默认使用const,并且仅在希望允许修改的情况下删除它。因此,将它应用于Foo::bar的参数是一个好主意。我认为这是一个很好的实践,尽管我应该承认我很少使用它,因为它会产生一些噪音,这可能会降低可读性。

另一件需要考虑的事情是,对于基本类型,或者更准确地说,不是指针或不包含指针的类型,修改按值传递的实参(即:(不是通过引用)不会有任何副作用:这些类型的参数实际上充当初始化的局部变量(这可能很方便,但也可能令人困惑)。对于指针,对指向数据的任何修改都将泄露给外部世界。这是在指针和类型的指向部分同时使用const限定符的另一个很好的理由。

总而言之,尽可能多地使用const限定符将有助于使代码更不容易出错,还可以帮助编译器优化生成的程序。

使用这些类型的引用不应该有任何明显的改变,如果这些类型描述的值适合CPU寄存器(通常是这种情况),

因此,该方法的所有三个版本都应该归结为生成的相同汇编代码。

在基本返回类型的特殊情况下,这无关紧要。返回值可以来回转换为符合const标准的值。

其他人也提到了const限定符对函数本身的兴趣。虽然超出了原来的问题范围,但我也会说,如果可能的话(如Foo::bar),将函数限定为const确实更好。

第二版和第三版之间没有任何区别。选择输入时间最短的一个:)

第一个和第三个有一点不同。如果您担心不小心修改函数中的ab,您可能更喜欢第三种方法。

简短的回答:没关系。

长答:因为你是按值传递两个实参并按值返回实参。这两种都可以,但您更经常看到的是第一个版本。

如果你通过引用传递(就像其他人建议的那样),那么它确实很重要,你应该使用const-reference。然而,通过引用传递基本类型并没有真正给您带来任何好处或意义(如果它是const引用)。这样做的原因是,与按引用传递基本类型相比,按值传递基本类型不会产生任何开销。

我要说的是,对于原语来说,实际复制它们可能更有效。当你传递一个引用时,编译器仍然必须在堆栈上传递字节,然后必须对地址解引用以获得内容。

此外,按值传递克服了任何可能的并发性/波动性问题,这些问题与正在传递的内存有关。

这是一个"不要试图在这里优化"的例子。

按const返回是一种风格。我通常不这样做,其他人更喜欢这样做,以防有人要对返回值做一些事情。接下来你会发现人们通过r值引用返回它们…

我通常会选择你的第一个选项。另一种方法是按值传递(不需要使用const)并按const值返回。