В классовых иерархиях поиск имен в шаблонных базовых классах не происходит.
Есть 3 способа заставить компилятор выполнять поиск имен в шаблонных базовых
классах:
1. Обращаться к именам посредством указателя this;
2. Ввести имена базовых классов с помощью using-объявления;
3. Выполнять полную квалификацию имени при обращении, но это отключает механизм
динамического связывания;
В GCC поиск в шаблонных базовых классах не
выполняется согласно стандарту.
В MSVC поиск в шаблонных базовых классах
происходит и ошибка не выдается.
Пример:
template<typename T>
class Base
{
public:
T
value;
Base()
: value() {}
virtual ~Base() {}
void f() {
cout << "Base::f\n"; }
virtual void v() { cout << "virtual Base::v\n"; }
virtual void call() { cout
<< "Base::call\n"; }
};
template<typename T>
class Derived : public Base<T>
{
virtual void v() { cout << "virtual Derived::v\n"; }
public:
// По стандарту код ф-ии call должен приводить к ошибке компиляции,
// но в MSVC поиск в шаблонных базовых классах происходит и ошибки
нет.
virtual void call()
{
cout
<< ">>>
Derived: value == " << value << "\n"; // Не должен находить value.
f(); // Не должен находить f.
v();
}
};
template<typename T>
class Derived_this : public Base<T>
{
virtual void v() { cout << "virtual Derived_this::v\n"; }
public:
virtual void call() // this включает поиск.
{
cout
<< ">>>
Derived_this: value == " << this->value << "\n";
this->f();
this->v();
}
};
template<typename T>
class Derived_using : public Base<T>
{
// using имен базового класса делает их видимыми.
using Base<T>::value;
using Base<T>::f;
using Base<T>::v;
public:
virtual void v() { cout << "virtual Derived_using::v\n"; }
virtual void call()
{
cout
<< ">>>
Derived_using: value == " << value << "\n";
f();
v();
}
};
template<typename T>
class Derived_explicit_call : public Base<T>
{
virtual void v() { cout << "virtual
Derived_explicit_call::v\n"; }
public:
// Явный вызов с полной квалификацией имени выполняет поиск в базовом
// классе, но отключает динамическое связывание.
virtual void call()
{
cout
<< ">>>
Derived_explicit_call: value == " << Base<T>::value << "\n";
Base<T>::f();
Base<T>::v();
}
};
int main()
{
Base<int>* pb =
new Derived<int>;
Base<int>* pb_this = new
Derived_this<int>;
Base<int>* pb_using = new Derived_using<int>;
Base<int>* pb_expl_call = new Derived_explicit_call<int>;
pb->call();
pb_this->call();
pb_using->call();
pb_expl_call->call();
delete pb;
delete pb_this;
delete pb_using;
delete pb_expl_call;
return 0;
}
Источник: Скотт
Мэйерс Эффективное использование C++. 55
верных способов улучшить структуру и код ваших программ.
По мотивам правила 43.
Wynn Las Vegas casino | JamBase
ОтветитьУдалитьLocated in the heart of the Las 용인 출장안마 Vegas Strip, this 4-star hotel and casino 고양 출장마사지 is adjacent to The Cosmopolitan. The hotel features 순천 출장샵 5 restaurants, a 통영 출장마사지 full-service 밀양 출장마사지