2017-01-20 14 views
1

У меня есть интерфейс и несколько классов, реализующих этот интерфейс.C++ - Как я могу делегировать все вызовы функций-членов для класса члену того же интерфейса

У меня также есть класс, который просто действует как оболочка, которая просто делегирует все вызовы членам, которые также реализуют этот интерфейс.

#include <iostream> 

class IFoo { 
public: 
    virtual void a() = 0; 
    virtual int b(int) = 0; 
    virtual bool c() = 0; 
}; 

class Foo : public IFoo { 
public: 
    void a() override { std::cout << "Foo::a" << std::endl; }; 
    int b(int x) override { std::cout << "Foo::b" << std::endl;}; 
    bool c() override { std::cout << "Foo::c" << std::endl; }; 
}; 

class Foo2 : public IFoo { 
public: 
    void a() override { std::cout << "Foo2::a" << std::endl; }; 
    int b(int x) override { std::cout << "Foo2::b" << std::endl;}; 
    bool c() override { std::cout << "Foo2::c" << std::endl; }; 
}; 

class DelegatingFoo : public IFoo { 
public: 
    DelegatingFoo(IFoo* f) : foo(f) {} 

    void a() override { return foo->a(); } 
    int b(int x) override { return foo->b(x); } 
    bool c() override { return foo->c(); } 
private: 
    IFoo* foo; 
}; 

int main() { 
    Foo foo; 
    DelegatingFoo dfoo(&foo); 
    dfoo.a(); 
    dfoo.b(5); 
    dfoo.c(); 

    Foo2 foo2; 
    DelegatingFoo dfoo2(&foo2); 
    dfoo2.a(); 
    dfoo2.b(5); 
    dfoo2.c(); 
} 

мне было интересно, если я мог бы просто направить звонки с DelegatingFoo на его член Foo, без того, чтобы определить все перегруженные методы, так что если я внести изменения в интерфейс IFoo, я бы не нужно полностью измените класс DelegatingFoo.

В моем случае класс DelegatingFoo действует как базовый класс для других оболочек, поэтому этим оберткам не нужно повторно реализовывать все переадресованные методы.

+0

Зависит от того, почему существует 'DelegatingFoo', что он добавляет? в чем разница между 'DelegatingFoo' и' Foo'? – Drax

+0

В моем случае он действует как базовый класс для других оболочек, так что им не нужно повторно выполнять все эти функции снова. – Andrew

+2

Почему бы не прямо унаследовать от 'Foo'? В настоящее время ваш 'DelagatingFoo' является базовым только указателем на' Foo' – Drax

ответ

0

Можно написать макрос, который выглядел как

DEFINE_METHOD(SCOPE, NAME, RETURN_TYPE, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) 

затем

DECLARE_INTERFACE(SCOPE, NAME) 
IMPLEMENT_FORWARD(SCOPE, NAME, TARGET) 

, но вы не должны.

И я не буду учить вас, как. Если вы хотите знать, как другие сделали что-то подобное, перейдите в библиотеку препроцессора master boost. Взломы находятся вне зла, код хуже, и результат трудно поддерживать и почти невозможно отлаживать.

Теперь идет работа по добавлению отражения и овеществления к стандарту C++. Отражение, скорее всего, произойдет первым, в C++ 20 или C++ 2 *. Повторение может произойти позже. Кажется, что вам нужны оба.

Отражение - это то, где вы можете работать со структурами данных времени компиляции, такими как интерфейсы в C++ (они планируют это делать и во время компиляции). Reification - это то, где вы создаете новый код на C++, возможно, основываясь на информации отражения.