Подтвердить что ты не робот

Какая разница между функцией-членом-константой и функцией не-const-члена?

Я очень запутался в функции версии const и не-const, как показано ниже:

value_type& top() { return this.item }
const value_type& top() const { return this.item }

В чем разница между этими двумя функциями? В какой ситуации они будут использоваться?

4b9b3361

Ответ 1

Короче говоря, они используются для добавления "const correctness" в вашу программу.

value_type& top() { return this.item }

Используется для предоставления изменяемого доступа к item. Он используется для изменения элемента в контейнере.

Например:

c.top().set_property(5);  // OK - sets a property of 'item'
cout << c.top().get_property();  // OK - gets a property of 'item'

Одним из распространенных примеров этого шаблона является возврат измененного доступа к элементу с помощью vector::operator[int index].

std::vector<int> v(5);
v[0] = 1;  // Returns operator[] returns int&.

С другой стороны:

const value_type& top() const { return this.item }

Используется для предоставления const доступа к item. Он более ограничительный, чем предыдущая версия, но имеет одно преимущество - вы можете называть его объектом const.

void Foo(const Container &c) {
   c.top();  // Since 'c' is const, you cannot modify it... so the const top is called.
   c.top().set_property(5);  // compile error can't modify const 'item'.
   c.top().get_property();   // OK, const access on 'item'. 
}

Чтобы следовать примеру вектора:

const std::vector<int> v(5, 2);
v[0] = 5;  // compile error, can't mutate a const vector.
std::cout << v[1];  // OK, const access to the vector.

Ответ 2

Функция const-квалифицированного члена будет вызываться, если функция-член вызывается на объекте, который является const-квалифицированным.

Неконстантно-квалифицированная функция-член будет вызываться, если функция-член вызывается для объекта, который не является const-квалифицированным.

Например:

MyStack s;
s.top(); // calls non-const member function

const MyStack t;
t.top(); // calls const member function

Обратите внимание, что те же правила применяются при вызове функции-члена при ссылке на объект или указателем на объект: если указатель или ссылка является объектом const, будет вызвана функция-член-член; иначе будет вызвана функция non-const member.

Ответ 3

Если у вас

class Foo
{
    value_type& top() { return this.item }
    const value_type& top() const { return this.item }
}

Если у вас

Foo foo;
const Foo cfoo;

Возвращаемые типы при вызове top() следующие:

value_type& bar = foo.top();
const value_type& cbar = cfoo.top();

Другими словами - если у вас есть постоянный экземпляр вашего класса, версия const функции выбирается как перегрузка для вызова.

Причина этого (в данном конкретном случае) заключается в том, что вы можете выдать ссылки на членов (например, item в этом случае) из экземпляра const класса и убедиться, что они тоже являются константами, поэтому не поддаются изменению и, следовательно, сохраняя константу экземпляра, из которого они пришли.

Ответ 4

Когда функция-член объявляется как const, происходит то, что неявный параметр указателя this, переданный функции, набирается как указатель на объект const. Это позволяет вызывать функцию с использованием экземпляра объекта const.

value_type& top();    // this function cannot be called using a `const` object
const value_type& top() const; // this function can be called on a `const` object

Ответ 5

value_type& top() { return this.item; } гарантирует, что либо члены данных вызывающего объекта могут быть изменены, либо может быть возвращено.

value_type& top() const { return this.item; } гарантирует, что члены данных вызывающего объекта не могут быть изменены, но возвращаемое значение может быть. Так, например, если я выполняю value_type item_of_x = x.top();, item_of_x можно изменить, но x не может. В противном случае возникает ошибка компилятора (например, наличие кода this.item = someValue; внутри тела функции).

const value_type& top() { return this.item; } гарантирует, что членам данных вызывающего объекта разрешено изменять, но возвращаемого значения быть не может. Это противоположно тому, что обсуждается выше: если я выполняю const value_type item_of_x = x.top();, item_of_x не может быть изменен, но x может. ПРИМЕЧАНИЕ value_type item_of_x = x.top(); все еще допускает модификацию item_of_x, поскольку item_of_x теперь не const.

const value_type& top() const { return this.item; } гарантирует, что ни члены данных вызывающего объекта не могут быть изменены, ни возвращаемое значение не могут быть.