#c #templates #inheritance #name-lookup #qualified-name
#c #шаблоны #наследование #поиск по имени #квалифицированное имя
Вопрос:
Я читаю полное руководство по шаблонам электронных книг и вопрос, который я собираюсь задать, может показаться вам глупым, но..
В этом 9.4.2 есть раздел зависимых базовых классов, который я не могу понять.
Вот частичный текст из него: http://tinypaste.com/633f0
// Variation 2:
template<typename T>
class DD2 : public Base<T> {
public:
void f() { Base<T>::basefield = 0; }
};
Мне нужна помощь в визуализации строки (или проблемной области) в тексте выше «С этим решением необходимо соблюдать осторожность, потому что, если для формирования вызова виртуальной функции используется неквалифицированное независимое имя, то квалификация блокирует механизм виртуального вызова и значение программы меняется. Тем не менее, бывают ситуации, когда первый вариант не может быть использован, и эта альтернатива подходит «
Я понимаю неквалифицированное независимое имя и т. Д., Но смешивание их с вызовом виртуальной функции — это то, что ускользает от меня.
Комментарии:
1. Это ужасное предложение, не так ли, этот код, похоже, предназначен для обеспечения невиртуального полиморфного поведения. Т.е. ваш производный класс может переопределять методы в вашем базовом классе, но поиск выполняется во время компиляции. Я подозреваю, что «Запрещение» в этом смысле означает, что вы не получите обычный динамический поиск во время выполнения на основе vtable….
2. Требуется больше контекста. Какую проблему пытается решить этот код?
Ответ №1:
Если квалифицированное имя (базовое поле) является виртуальной функцией, то квалификация запрещает виртуальный вызов. Это почти то же самое, как если бы у вас:
struct Base {
virtual void vCall() { }
};
struct Derived : public Base {
virtual void vCall() { }
};
int main() {
Derived d;
Base* inst = amp;d;
inst->Base::vCall(); // By qualifying we won't get virtual dispatch;
// this calls Base::vCall directly
}
Ответ №2:
Использование квалифицированного идентификатора class-name::function()
препятствует виртуальности function
, поэтому вместо этого следует использовать this->function()
.
Это также работает для элементов данных : this->basefield
.