Здравствуйте коллеги!
Такой код:
namespace cli
{
namespace wtl
{
template <class TBase>
class CFrameHlp : public TBase
{
...
class CMainFrame : public ::cli::wtl::CFrameHlp<CMainFrame>
{
...
не компилируется, говорит, что
>gui\wtl\framehlp.h(33) : error C2504: 'CMainFrame' : base class undefined
1>\mainfrm.h(35) : see reference to class template instantiation 'cli::wtl::CFrameHlp<TBase>' being compiled
1> with
1> [
1> TBase=CMainFrame
1> ]
Что-то не пойму, в чем дело, ведь такой прием вполне хорошо используется в WTL. Может кто свежим глазом заметит косяк?
Здравствуйте, Marty, Вы писали:
M>Что-то не пойму, в чем дело, ведь такой прием вполне хорошо используется в WTL. Может кто свежим глазом заметит косяк?
В WTL используется CRTP
template<class TMostDerived, AnyParams>
class SomeMixin : AnyBases<AnyParams>
// можно унаследоваться от каких-нибудь ещё баз, в т.ч. параметризованных; или прямо от параметра, как частный случай
{
protected: // или public
void foo() { ..... } // для потомка
void bar()
{
static_cast<TMostDerived*>(this)->buz0(); // от потомка
static_cast<TMostDerived*>(this)->buz1(); // от потомка
// то же самое на виртуальных функциях выглядело бы так
vbuz0();
vbuz1();
}
//void buz0() нужно определить в потомке
void buz1() { ..... } // можно переопределить в потомке
virtual void buz0() = 0;
virtual void buz1() { ..... }
};
.....
class MyMostDerivedObject : ....., public SomeMixin<MyMostDerivedObject, blablabla>, .....
{
public:
// интерфейс к предку
void buz0() { ..... }
void buz1() { ..... } // если не устраивает дефолтная реализация
virtual void vbuz0() { ..... }
virtual void vbuz1() { ..... }
};
Отличия и выгоды CRTP перед виртуальными функциями — это, во-первых, большая гибкость, а во-вторых, отсутствие накладных расходов на виртуальность.
А невыгоды — необходимость протащить TMostDerived через всю иерархию промежуточных классов, и поскольку это шаблоны, вытащить кучу кода на общее обозрение в .h-файлы.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Здравствуйте, denisko, Вы писали:
D>Ты хочешь CMainFrame унаследовать от CMainFram'a занятие до боли увлекательное.
Для поставившего минус: подтверждаю, именно так. CMainFrame наследуется от CFrameHlp<CMainFrame>, а тот наследуется от CMainFrame. Вуаля.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Здравствуйте, Marty, Вы писали:
M> Здравствуйте коллеги!
M> Такой код:
M>M>namespace cli
M>{
M>namespace wtl
M>{
M>template <class TBase>
M>class CFrameHlp : public TBase
M>{
M>...
M>class CMainFrame : public ::cli::wtl::CFrameHlp<CMainFrame>
M>{
M>...
M>
M>не компилируется, говорит, что
M>>>gui\wtl\framehlp.h(33) : error C2504: 'CMainFrame' : base class undefined
1>>\mainfrm.h(35) : see reference to class template instantiation 'cli::wtl::CFrameHlp<TBase>' being compiled
1>> with
1>> [
1>> TBase=CMainFrame
1>> ]
M>Что-то не пойму, в чем дело, ведь такой прием вполне хорошо используется в WTL. Может кто свежим глазом заметит косяк?
не считая
упомянутойАвтор: denisko
Дата: 23.10.09
проблемы, то что ты хочешь делается вот так:
class A; // declaire
class A : public B<A>
{
// define
};