Единственный раз, когда вы можете сделать это, это когда что-то получено из шаблона, который сам параметризован:
template<typename T> class base
{
T* down_cast() throw()
{
return static_cast<Derived*>(this);
}
const T* down_cast() const throw()
{
return static_cast<const Derived*>(this);
}
public:
base()
{
down_cast()->doSomething();
}
/* … */
};
class derived : private base<derived>
{
public:
void doSomething()
{
}
};
Обратите внимание, что doSomething
является общедоступным, а не виртуальным.
Мы можем сделать static_cast с производным, потому что известно, что производный является производным типом.
Получение чего-либо из базы, параметризованной само по себе, - странная вещь, которую нужно делать в лучшие времена.Говорят, что когда команда ATL в Microsoft использовала его, они спрашивали команду компилятора C ++, была ли она действительной, и никто не был уверен, хотя она действительна, потому что построение шаблона зависит от имен следующим образом:
Сначала шаблон доступен, но не используется в классе.Затем имя derived
доступно.Затем он создает макет base<derived>
- это требует знания переменных-членов и виртуальных функций, если только это не зависит от знания макета derived
(с указателями и ссылками все в порядке), все будет хорошо.Затем он создаст макет derived
и, наконец, создаст функции-члены derived
, которые могут включать создание функций-членов для base<derived>
.Таким образом, до тех пор, пока base<derived>
не содержит производную переменную-член (базовые классы никогда не могут содержать переменную-член типа, производного от себя) или виртуальную функцию, требующую знания макета производного, мы действительно можем выполнить сложный образо наследовании выше.
Это включает в себя возможность вызывать не виртуальные открытые члены derived
из base
во время построения, потому что это уже часть базы.Есть серьезные ограничения на это.В частности, если doSomething()
зависит от чего-либо созданного в конструкторе derived
, оно не будет работать, так как derived
еще не было построено.
Теперь, действительно ли это хорошая идея?Нет.