Как компилятор определяет, какие функции-члены мутируют?

StackOverflow https://stackoverflow.com/questions/1230677

Вопрос

Меня заинтересовал комментарий к одному из моих постов:

Я тоже.Я также даю аксессорам/мутаторам то же имя.

Мне было интересно об этом, потому что я всегда использовал setBar(int bar) вместо мутатора названо то же самое.Я хочу знать:может ли компилятор определить на основе константного идентификатора, что меняется во время выполнения, или он может использовать то же имя функции, поскольку у нее есть параметр?

Будет ли это компилироваться нормально:

class Foo
{
   int bar_;

   public:
      int bar() { return bar_; }
      void bar(int bar) { bar_ = bar; }
}

Или мне нужно сделать это (я понимаю, что мне все равно следует это сделать, просто поговорите со мной об этом):

int bar() const { return bar_; }

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

Почему это работает именно так?

Это было полезно?

Решение

Первое, на что смотрит компилятор, это количество и тип параметров, которые вы передаете в функцию. Это устраняет перегрузку на bar еще до того, как ей даже нужно взглянуть на const -ness.

Если вам не удастся пометить bar () как const , компилятор сообщит вам об этом при первой попытке вызова bar () в const экземпляре объекта.

Другие советы

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

Как говорит Грег, компилятор будет возражать, когда вы попытаетесь вызвать неконстантную функцию-член для константного объекта (опять же, не имеет значения, мутирует ли она на самом деле.Единственное, что важно, это объявлено ли оно как const).

Для облегчения понимания учтите, что компилятор предполагает, что объект будет изменен, если для этого объекта будет вызван неконстантный метод.

Таким образом, в методе const, если вы вызываете неконстантный метод для одного из членов данных или другого неконстантного метода класса, компилятор выдаст сообщение об ошибке.

Вы также можете рассматривать операторы как методы (я знаю, вы можете определить некоторые операторы как дружественные функции, но не как методы, а для упрощения ...). Например, оператор присваивания (operator =) по умолчанию не является константным. Это означает, что если вы делаете что-то вроде

void MyClass::MyConstMethod() const
{
   classMember = value;
}

Компилятор будет считать, что вы вызвали оператор присваивания classMember, который внутри метода const является объектом const. Так как operator = не является константой, будет сообщено об ошибке компилятора.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top