Рассмотрим это
#include <iostream>
int f(int num) { return num+1; }
int fr(int& num) { return num+1; }
int fcr(const int& num) { return num+1; }
class D
{
public:
int value= 0;
public:
void f1() { value++; }
int f2() const { return value; }
int f3() { return value; }
static void f4() { std::cout << "Hello" << std::endl; }
void f5() const;
};
void D::f5() const
{
// Prohibited:
// f1(); // modifies this
// f3(); // might modify this
// value++; // modifies this->value, thus modifies this
// value= 2; // modifies this->value, thus modifies this
// value= abs(value); // modifies this->value, thus modifies this
// fr(value); // takes value by reference and might modify it
//
// Permitted:
f2(); // const function, does not modify this
std::cout << value << std::endl; // independent function, does not modify this; read access to this->value is const
std::cout << abs(value) << std::endl; // independent function, does not modify this; read access to this->value is const
f4(); // static function, does not modify this
f(value); // function, does not modify this; takes value as read only (makes copy)
fcr(value); // function, does not modify this; takes value as read only by reference
D otherObject;
otherObject.f1(); // modifies otherObject (non const), does not modify this
}
int main()
{
const D d;
d.f5();
}
Всякий раз, когда вы вызываете функцию-член, например f4()
внутри f5()
, вы передаете неявный указатель this
, эквивалентный this->f4()
. Внутри f5()
, как и const
, это не тип D*
, а const D*
. Таким образом, вы не можете сделать value++
(эквивалентно this->value++
для const D*
. Но вы можете позвонить abs
, printf
или что-то еще, что не займет this
и попытается изменить его).
Когда вы берете this->value
, если this
тип равен D*
, это тип int
, и вы можете изменить его. Если вы сделаете то же самое с const D*
, его тип станет const int
, вы не сможете изменить его, но сможете скопировать и получить доступ к нему как к справочнику const для чтения.