Разница между С++ между добавлением константы с static_cast и const_cast объекта "this"?
Как и Скотт Мейерс, чтобы предотвратить повторение кода в версии const getter и неконстантной версии getter, вызовите версию версии метода из неконстантной версии: static_cast<const A&>(*this).Methodology();
, однако, в случайное использование из-за чрезмерного зрения Visual Assist X Intellisense Я набрал: const_cast<const A&>(*this).Methodology();
, и он работал нормально.
Каковы все и все различия в этом случае с использованием конкретного литья?
IDE: Visual Studio 2010.
Ответы
Ответ 1
Предполагая, что тип this
равен A*
, нет разницы.
В общем случае const_cast
может отличать спецификатор const
(от любого уровня параметра косвенности или шаблона)
static_cast<>
может передавать тип другому, если целевой тип находится в иерархии исходного типа.
Они не могут работать друг с другом.
Причина, по которой они работали в вашем случае, состоит в том, что вы ввели константу, в отличие от ее удаления (вызов из неконстантной версии функции типа this
равен A*
, no Const). Вы могли бы просто написать
const A& tmp = *this;
tmp.Methodology();
и это сработало бы без необходимости кастинга. Кастинг используется для удобства и ограниченности, чтобы не вводить новую переменную.
Примечание: вы можете использовать static_cast<>
здесь, как вы знаете, что вы производите правильный тип. В других случаях (когда вы не можете быть уверены) вам нужно использовать dynamic_cast<>
, который выполняет проверку типа времени выполнения, чтобы убедиться, что преобразование действительно.
Ответ 2
После повторного чтения пункта 3 из Effective C++ 3rd Ed.
я понимаю, что он действительно выступал за использование обоих. Добавьте const для вызова версии const, затем отбросьте константу возвращаемого значения (если она есть). В моем конкретном случае нет значения const const, просто const-function, поэтому версия wrapped-by -cast_cast < > не нужна и фактически вызывает разницу между двумя указанными вызовами
(стр. 13) Пункт 3: Используйте const по возможности
...
(стр. 23) Избегайте дублирования в const и Не const Функции-члены
... То, что вы действительно хотите сделать, это реализовать функцию operator [] один раз и использовать его дважды. То есть, вы хотите иметь одну версию оператор [] вызывает другой. И это приводит нас к отбрасыванию совести.
... Отбрасывание константы на возвращаемое значение является безопасным, в этом случае, потому что тот, кто вызвал неконстантный оператор [], должен был иметь не-const-объект в первую очередь.... Так что наличие неконстантного оператор [] вызывает версию const, это безопасный способ избежать кода дублирование, даже если для этого требуется бросок...
class TextBlock {
public:
...
const char& operator[](std::size_t position) const //same as before
{
...
...
...
return text[position];
}
char& operator[](std::size_t position) //now just calls const op[]
{
//cast away const on op[] return type;
//add const to *this type;
//call const version of op[].
return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);
}
...
};
Как вы можете видеть, код имеет два броска, а не один. Мы хотим, чтобы неконстантный оператор []... Чтобы избежать бесконечной рекурсии, мы должны укажите, что мы хотим вызвать оператор const [], но там нет прямой способ сделать это. Вместо этого мы накладываем * это на свой собственный тип TextBlock & to const TextBlock &. Да, мы используем cast для добавления сопз! Итак, у нас есть две команды: одна добавляет const к * этому (так что наш вызов operator [] вызовет версию const), второй - удалите константу из возвращаемого значения * const operator [].