Здравствуйте, Кодт, Вы писали:
К>Ну а чтоб и компилятор не перетруждать — тут уж только ифдефить повсеместно.
К>Либо как-то выразить B() единообразно через другие члены наследника (т.е. воплотить паттерн Шаблонный Метод), и соответственно, ифдефить B() в промежуточном базовом классе.
К>Причём шаблонный метод можно сделать как на виртуальных функциях, так и на CRTP. Это уже нюансы.
К>К>// эта пусть будет на виртуальных функциях
К>class CommonImpl1 : public IA
К>{
К>#ifdef COMPILE_B
К>private: // ибо незачем наследникам вызывать то, что может быть исключено из компиляции
К> virtual void B() { this->foo(); this->bar(); }
К>protected:
К> virtual void foo();
К> virtual void bar();
К>#endif
К>};
Ааээ а чем это отличается от просто виртуальных функций? В наследниках тоже будут свои реализации foo() и bar() и их тоже надо будет ифдефить. На оставленные без деклараций тела компилятор будет ругаться. В чем выигрыш?
К>// а эта на CRTP
А CRTP работает дальше одного наследника? А как?
class IA{..}
template< class T >
class IB
{
public:
#ifdef USE_B
void b()
{
static_cast<T*>(this)->b_impl();
}
#endif
};
class Base : public IA, public IB<A>
{
public:
void b_impl(){...};
};
class B: public Base, public IB<B> (?)
{
public:
void b_impl(){...};
};
int main()
{
Base *ca = new Base();
Base *cb = new B();
#ifdef USE_B
ca->b(); // <-- Base::b_impl
cb->b(); // <-- тоже Base::b_impl
#endif