Йа волосат и бородат!
...когда я бежал к глазодерам. =О.о=
Все знают ситуацию, когда нужно пронаследовать несколько детишек от некоторого класса. И все знают, чем плохо перегружать в детишке невиртуальный метод, а именно что будет, если попробовать вызвать перегруженный метод по указателю на родителя. (перегруженный метод банально не вызовется, ибо в таблицу виртуалов не попадет)
Так вот для преодоления такой фигни в случае закрытого кода с родительским классом возникла мысль написать что-нить вроде:
Наследоваться надо вот так:
При этом получается, что в момент наследования от Middle_base класс Child уже обьявлен в той же строке.
Единственный минус конструкции - что обращаться надо по указателю на Middle_base.
Единственный вопрос возникает - нафига при таком подходе вообще нужны виртуальные методы? =О.о=
ЗЫ: Учитывая, что это была только мысля, которую я еще не довёл до ума...
UPD: К сожалению, на проверке метода выявились 2 проблемы:
1) не происходит вызова Middle_base::operator-> (). Вызов сразу уходит в Base;
2) совершенно непонятно, что делать с самим классом Middle_base . Ибо каждый из них порождает отдельный тип, а это как бы мешает в случае кучи детишек. :/
Все знают ситуацию, когда нужно пронаследовать несколько детишек от некоторого класса. И все знают, чем плохо перегружать в детишке невиртуальный метод, а именно что будет, если попробовать вызвать перегруженный метод по указателю на родителя. (перегруженный метод банально не вызовется, ибо в таблицу виртуалов не попадет)
Так вот для преодоления такой фигни в случае закрытого кода с родительским классом возникла мысль написать что-нить вроде:
template <typename Derived_class>
class Middle_base : public Base {
public:
Derived_class * const operator-> () {
return reinterpret_cast <Derived_class * const> (this);
}
};
Наследоваться надо вот так:
class Child : public Middle_base <Child>
{
// ...
};
При этом получается, что в момент наследования от Middle_base класс Child уже обьявлен в той же строке.

Единственный вопрос возникает - нафига при таком подходе вообще нужны виртуальные методы? =О.о=
ЗЫ: Учитывая, что это была только мысля, которую я еще не довёл до ума...
UPD: К сожалению, на проверке метода выявились 2 проблемы:
1) не происходит вызова Middle_base::operator-> (). Вызов сразу уходит в Base;
2) совершенно непонятно, что делать с самим классом Middle_base . Ибо каждый из них порождает отдельный тип, а это как бы мешает в случае кучи детишек. :/
Ну на первый взгляд все намана, кроме одного:
Derived_class * const operator-> () {
return reinterpret_cast (this);
}
вернет самого себя, а оператор -> задан у него так чтоб вернуть себя - рекурсии не будет?
тока стоит ли виртуализовавать невиртуальные методы? Понятно, это зависит от ситуации....
В принципе с тем же успехом можно в middleclass объявить нужную виртуальную функуию и сначала кастовать в middleclass. Тебе и тут нуна делаеть такое кастование.
Еще минус: для наследников класса Child (у которого д/б своя реализация метода) будет нехорошо
Тимур
нет, он возвращает не самого себя, а своего наследника.
В принципе с тем же успехом можно в middleclass объявить нужную виртуальную функуию и сначала кастовать в middleclass. Тебе и тут нуна делаеть такое кастование.
А если нужна именно перегрузка?
Еще минус: для наследников класса Child (у которого д/б своя реализация метода) будет нехорошо
Ага... есть такое.
нет, он возвращает не самого себя, а своего наследника.
да, нормально все, возвращается ж указатель, а не сцылка.
А если нужна именно перегрузка?
В смысле?! как это соотносится с первонамальным вопросом?
Кстати, варварский (грю сразу, чтоб не холиварили) способ в принципе пройдет?
Тут есть вопрос. в хранится ли либе таблица виртуальных функций для класса, реализованного в этой либе, или эта таблица строится при компиляции проекта, который ее в себя включает?
Если второе, то в h-файле можно в наглую сказать ему виртуал %(((
Ссылка тоже прокатила бы, кстати. Они тоже прекрасно преобразуются, если ты не знал.
Учитывая UPD и провал тестов, есть ли смысл продолжать дискуссию?
В борладне точно низя, интересно - есть которые позволяют?
хз. у меня других идей нету.
чтобы ИЗНУТРИ класса закрытой библиотеки вызывался унаследованный метод (от невиртуального) - ты это в принципе не сделаешь, т.к. код уже скомпилирован....
а если извне - то эта проблема решаема...
нет, он возвращает только указатель. Однако, сделать метод вида Type & Method () тоже можно.