函数参数或声明中的C ++常量正确性

时间:2019-05-17 17:45:45

标签: c++

我想知道是否有必要将const放在函数的参数和参数中以实现const的正确性。

我的理解是const正确性是对不更改变量的承诺。

例如:

bool operator==(const rational<T>& rat);
bool operator!=(const rational<T>& rat);

bool operator==(const rational<T>& rat) const;
bool operator!=(const rational<T>& rat) const;

等效吗?

我当时想主要是因为如果您不更改参数,它们就不会更改类中的任何内容,或者它们是不同的,因为您可以更改公共/私有成员的值,但不能传入参数。

如果使用不当,请更正我的术语。

3 个答案:

答案 0 :(得分:5)

const最后适用于this(使其成为指向常量的指针),这意味着成员函数将不会修改调用它的对象

class Cls {
 public:
  void f() {
    ++x_; // no problem
  };

  void g() const {
    ++x_; // error, can't modify in const member function
  };

 private:
  int x_{};
};

在您的示例中,您想同时说明参数是const和this。在lhs == rhs中,lhs仅在尾随const时才被视为const,因此您可以使用

bool operator==(const rational<T>& rat) const;
bool operator!=(const rational<T>& rat) const;

(尽管您可能应该省略<T>

此外,如果省略尾随的const,则无法与左侧的const对象进行比较

const rational<int> a;
const rational<int> b;
if (a == b) { // error if you don't have the trailing const on operator==

答案 1 :(得分:2)

我赞成赖安斯(Ryans)和现在已撤消的答案,但为了说明这一点:

bool operator==(rational<T>& rat);

ratthis都可以更改。


bool operator==(const rational<T>& rat); // equivalent to the below
bool operator==(rational<T> const& rat); // equivalent to the above

this可以更改。


bool operator==(rational<T>& rat) const;

rat可以更改。


bool operator==(const rational<T>& rat) const; // equivalent to the below
bool operator==(rational<T> const& rat) const; // equivalent to the above

ratthis都不能更改-对于此特定操作符,这是预期的行为。


正如user4581301所指出的,使所有内容尽可能地为const使得编译器可以考虑在更多情况下使用该函数,而不是仅使用const实例。它也很乐意将其用于非const。除此之外,优化器还可以使用const信息。它可以使生成的可执行文件更快,而const甚至可以使其编译得更快。两者都有,因为它缩小了运行时和编译期间可能涉及的考虑范围。

如有疑问,请启动const

答案 2 :(得分:0)

const关键字的位置根据其放置位置而具有不同的含义。参数前的const关键字指定参数为常量,表示无法修改其值。如果将const关键字放在末尾,则表示调用函数的变量的值是常量,因此无法修改。

这里是一个例子:

class Foo
{
public:
   void First(const float& something) const;
   void Second(const float& something);
   void Third(float& something) const;
}

在第一个函数中,无法通过调用该函数来修改类型为Foo的变量(从中调用该函数)和变量something

在第二个函数中,可以通过该函数修改调用类型为Foo的变量。这意味着它可以更改其成员,从而更改变量。

在第三个函数中,可以修改变量something,但是不能从中调用类型为Foo的变量。例如,在想要更改类型为Foo的变量的成员的值而无需实际更改该值,而仅更改作为引用传递的变量的情况下,这很有用。