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

时间:2013-09-12 09:01:05

标签: c++ const

我有以下代码

#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对象调用时采取不同的行为?

3 个答案:

答案 0 :(得分:3)

  

我的问题是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是const?好吧,你在Foo的声明中告诉了它。

答案 1 :(得分:0)

  

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

符合const条件的begin() method has an overload返回const_iterator。被const限定意味着它是从被调用的对象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或非const迭代器取决于您要实现的任务。作为一般准则,除非您打算修改容器内的元素,否则始终使用const迭代器。

答案 2 :(得分:0)

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

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

void someMethod();
void someMethod() const;