Когда вы добавляете ключевое слово const
к методу, указатель this
по существу становится указателем на объект const
, и поэтому вы не можете изменять какие-либо данные члена. (Если вы не используете mutable
, об этом позже).
Ключевое слово const
является частью сигнатуры функции, что означает, что вы можете реализовать два похожих метода, один из которых вызывается, когда объект равен const
, а другой - нет.
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
Это выведет
Foo
Foo const
В неконстантном методе вы можете изменить элементы экземпляра, чего нельзя сделать в версии const
. Если вы измените объявление метода в приведенном выше примере на приведенный ниже код, вы получите несколько ошибок.
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
Это не совсем так, потому что вы можете пометить элемент как mutable
, а метод const
может изменить его. В основном он используется для внутренних счетчиков и прочего. Решением для этого будет следующий код.
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++;
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "The MyClass instance has been invoked " << ccc.GetInvocations() << " times" << endl;
}
что бы вывести
Foo
Foo const
The MyClass instance has been invoked 2 times