Как компилятор определяет, какие функции-члены видоизменяются? - PullRequest
0 голосов
/ 05 августа 2009

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

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

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

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

class Foo
{
   int bar_;

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

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

int bar() const { return bar_; }

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

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

Ответы [ 3 ]

4 голосов
/ 05 августа 2009

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

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

2 голосов
/ 05 августа 2009

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

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

0 голосов
/ 05 августа 2009

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...