调用 const 对象时的类成员函数行为

Class member function behaviour when calling const objects

本文关键字:成员 函数 const 对象 调用      更新时间:2023-10-16

我有以下一段代码

#include <string>
int Foo(const std::string& str){
    std::string::iterator start;
    start = str.begin();
    return 0;
}

当我使用 GCC 4.7.3 编译它时,我收到一个错误。因为我怀疑弹出错误是因为我试图分配一个

std::string::const_iterator; 

到一个

std::string::iterator

所以改变路线

std::string::iterator start; 

std::string::const_iterator start;
编译

精细。

我的问题是 std::string 成员函数 begin() 如何识别它调用的对象是 const 并因此返回一个const_iterator。

使问题更笼统:
我可以更改或以某种方式重载类成员函数以在被 const 对象调用时采取不同的操作吗?

我的问题是 std::string 成员函数 begin() 如何识别它被调用的对象是 const 并因此返回一个const_iterator。

begin有两个重载:

iterator       begin();
const_iterator begin() const;

选择哪一个取决于调用成员函数时隐式this参数的类型 - 在您的情况下,它要么是std::string&要么是const std::string&

N3337, 13.3.1

2 候选函数集可以包含要解析的成员函数和非成员函数 相同的参数列表。因此,参数和参数列表在此异构中具有可比性 Set,成员函数被认为具有一个额外的参数,称为隐式对象参数,它 表示已为其调用成员函数的对象。为了解决过载问题, 静态和非静态成员函数都具有隐式对象参数,但构造函数没有。

只能对const限定对象参数调用const限定成员函数。

编译器如何知道str是常量?好吧,你在Foo宣言中告诉了它.

如果您的对象是 const 对象,编译器会自动选择一个 const 成员函数。

您必须提供两个成员函数:

void someMethod();
void someMethod() const;

我的问题是 std::string 成员函数 begin() 如何识别 它被调用的对象是 const,因此返回一个 const_iterator。

begin()方法有一个重载,其中const限定的,返回一个const_iteratorconst限定意味着它是从中调用的对象const时使用的对象

iterator begin();
const_iterator begin() const;  // This one

strconst,调用第二个,因此返回的对象是一个const_iterator,你试图分配给一个无效的iterator,因此错误。


我可以更改或以某种方式重载类成员函数以执行操作吗 被 const 对象调用时不同?

使用auto!而不是做

std::string::iterator start;
start = str.begin();

auto start = str.begin();

这样,您实际上使用的是begin()返回的确切类型

但是,您可能以错误的方式做事,因为您需要常量还是非常量迭代器取决于您想要实现的任务。作为一般准则,请始终使用 const 迭代器,除非您打算修改容器内的元素。