Различие между константными и неконстантными версиями методов в C ++

У меня есть несколько вопросов относительно различий между константными и неконстантными версиями методов в C ++.

Пример:

      MyObject* MyClass::objectReference()
const MyObject* MyClass::objectReference() const

Мои вопросы:

  1. Есть ли вообще способ отличить, какая версия метода вызывается вручную? Или это полностью / полностью автоматический процесс, и если да, то каковы точные правила определения того, какая версия должна быть вызвана?
  2. Что касается (1), если вы не можете отличить вызов константной версии от неконстантной, значит, невозможно вызвать одну версию метода из другой, чтобы предотвратить дублирование?
  3. Как создать ссылку на ту или иную версию в документации одного из методов, использующих doxygen? (например, «константная версия myMethod ().» или «неконстантная версия myMethod ().») Я обнаружил это сам - просто добавьте или опустите «константу» в конце сигнатуры метода.

person Jake Petroules    schedule 04.08.2010    source источник
comment
Я предлагаю сделать # 3 другим вопросом - последний относится к Doxygen, а первый - к общим вопросам C ++. Разделение №1 и №2 тоже может работать лучше.   -  person Georg Fritzsche    schedule 04.08.2010
comment
# 2 - это просто частный случай # 1, где рассматриваемый объект - это тот, на который указывает this. Я определенно согласен с тем, что у № 3 должен быть свой вопрос.   -  person bcat    schedule 04.08.2010
comment
@bcat: Итак, может - совместное использование реализации представляет собой интересный вопрос сам по себе: # 1, # 2, # 3, ... :)   -  person Georg Fritzsche    schedule 04.08.2010


Ответы (2)


Я не знаю о доксигене; хотя вот что я знаю.

  1. Если есть только версия, отличная от const, ее просто нельзя вызвать для const объекта.
  2. Если есть только const версия, ее можно вызывать как для const, так и для объектов, отличных от const.
  3. Если есть и то, и другое, версия, отличная от const, будет вызываться для объектов, отличных от const, а версия const будет вызываться для const объектов.
  4. Если вы хотите явно вызвать const, вы должны привести свой объект к самой константной ссылке: static_cast<const MyClass&>(myObject).objectReference();
person zneak    schedule 04.08.2010
comment
Вы бы использовали вместо этого const_cast? - person Anthony; 04.08.2010
comment
@Duracell: Я бы предпочел использовать const_cast только для удаления модификатора const, поскольку static_cast отлично справляется с его добавлением. - person zneak; 04.08.2010
comment
@Duracell @zneak: это хороший вариант использования implicit_cast шаблон функции. - person James McNellis; 04.08.2010
comment
В гипсе нет необходимости. Лучше всего использовать приведение типов для сужения конверсий, добавление const - это расширяющая конверсия. Вместо этого просто инициализируйте ссылку, как в const MyClass& constmyObject = myObject; constmyObject.objectReference(); Это не может случайно сделать что-нибудь опасное. - person Ben Voigt; 04.08.2010
comment
@ Джеймс: Ах, я не знал, что это у Boost. Спасибо! - person bcat; 04.08.2010
comment
@Jake: Предложение Джеймса implicit_cast - это аккуратно обернутый способ выражения метода initialize-a-const-reference. Единственным недостатком является лишний заголовочный файл от boost. - person Ben Voigt; 04.08.2010
comment
Для полноты картины может быть интересно, что указатели на функции также могут использоваться для различения этих двух функций: (void (X::*)() const)&X::f; - полезно, например. для устранения неоднозначности с bind() et al. - person Georg Fritzsche; 04.08.2010

Хотя вызывать не-const метод на const экземпляре, вероятно, нецелесообразно. Однако, если вы хотите вызвать метод const на экземпляре, отличном от const, просто используйте приведение. См. Пример в следующей программе:

#include <iostream>

class ConstTest {
public:
  void cows() const {
    std::cout << "const method call" << std::endl;
  };

  void cows() {
    std::cout << "non-const method call" << std::endl;
  }
};

int main() {
  ConstTest ct;

  ct.cows();                                 // Prints "non-const method call"
  static_cast<const ConstTest &>(ct).cows(); // Prints "const method call"
}
person bcat    schedule 04.08.2010