为什么需要 const 引用和 const 成员函数?

Why the need for both const reference and const member function?

我正在做 "Programming Principles and Practice using C++" 的练习 我找到了一个 class 和这个成员函数 here:

const vector<string> &get_name() const { return name; }

其中名称是向量:vector< string> name

本书目前介绍了 2 个概念(直到第 235 页):

  1. return const 引用以防止函数更改 returning 值:

    const vector<string> &get_name() { return name; } 
    
  2. 一个不能修改对象的const成员函数。在这种情况下,它将是这样的:

    vector<string> get_name() const { return name; } 
    

也许我没有完全理解这一点,但这两个概念不是一样的吗? 不想更改 "name" 向量。

为什么需要两者 "const"?

感谢所有花时间回复的人!

一个成员函数有一个隐含的this-引用。

并且引用的对象可以是 const 限定的,允许在常量对象上调用成员函数,方法是在声明中的参数列表后面加上 const

该成员函数是否也 returns 对某些常量数据的引用可能有很强的相关性,但仍然完全由程序员决定。

这种情况 return 是对 vector<string> 的 const 引用,我们无法更改此向量。但是我们可以在这个函数中改变vector<string> name

const vector<string> &get_name() { return name; } 

在本例中 return vector<string> 的副本,我们可以更改此向量,因为它已经是另一个向量。在这个函数中我们不能改变vector<string> name.

vector<string> get_name() const { return name; } 
  1. return a const reference to prevent the function to change the returning value
  2. a const member function that cannot modify the object. in this case, it would be like this

这本来可以更清楚一点,我会尝试更好地解释它。

返回 const 引用可防止 returned 对象 callers.

改变

这是一个例子:

// let get_name be `const std::vector<std::string>& get_name()`

np1.get_name().size(); // ok, size is a const function of vector
np1.get_name().push_back("hello"); // ERROR! push_back is not a const function of vector

因此,调用者确实无法更改 name 向量。 return 类型是 const 限定的。

但是,如果函数 get_name 本身不是 const 限定的(不是 return 类型),则允许从 class 本身更改名称。

你看,成员函数接收一个隐藏的 this 参数,它是指向被调用对象的指针。指针可以指向 const 对象,也可以指向可变对象。这是比较:

// returning const ref, callers cannot change the name vector
const std::vector<std::string>& get_name() {
    // The function receive a `this` that points to a mutable,
    // we can change the name from the inside
    this->name.push_back("another");
    return name;
}

// the `this` pointer points to const -----v---v
const std::vector<std::string>& get_name() const {
    this->name.push_back("another"); // ERROR! Cannot mutate member of const object
    return name;
}

Const 限定的成员函数对调用者非常有用,因为它知道无论何时调用此函数,其状态都不会改变。

例如,不仅您知道 vector::size() 函数不会改变向量,而且编译器保证它,因为它是一个 const 限定成员函数。

最后一点,您在此处发布的代码:

vector<string> get_name() const { return name; } 

这不是 return 参考,而是复制。调用者可以随心所欲地改变副本,但不能改变 name 本身。

这里有一个复制变异的例子:

auto name_copy = np1.get_name();

name_copy.push_back("another name"); // works, we mutated the copy by adding an element