Какой самый простой способ удовлетворить чистый абстрактный метод методами из других базовых классов

Редактировать: В некоторых комментариях под простым я подразумеваю: а) меньше кода, б) легко поддерживать и в ) трудно ошибиться.

Правка №2: Кроме того, использование включения вместо частного наследования не вызывает возражений, если оно действительно упрощает реализацию InterfaceImpl .

В настоящее время я знаю, что единственный способ сделать это - поручить разработчику определить абстрактный метод и делегировать вызов методу целевого базового типа. Пример:

#include <iostream>
#include <memory>

class Interface
{
public:
    virtual void method1() = 0;
    virtual void method2(int x) = 0;
};

class MethodOneImpl
{
 private:
    void method1(int x)
    { std::cout << "MethodOneImpl::method1() " << x << std::endl; }

 public:
    void method1() { method1(0); }
};

class MethodTwoImpl
{
 public:
    void myFunc(int x)
    { std::cout << "MethodTwoImpl::myFunc(x)" << x << std::endl; }
};

class InterfaceImpl : public Interface
                    , private MethodOneImpl
                    , private MethodTwoImpl
{
public:    
    virtual void method1() { MethodOneImpl::method1(); }
    virtual void method2(int x) { MethodTwoImpl::myFunc(x); }
};

int main()
{
    std::unique_ptr<Interface> inf;
    inf.reset(new InterfaceImpl);
    inf->method1();
    inf->method2(0);

    // This should be disallowed!
    // std::unique_ptr<MethodOneImpl> moi;
    // moi.reset(new InterfaceImpl);
}

Сначала я подумал, что, возможно, это может решить проблему:

class InterfaceImpl : public Interface
                    , private MethodOneImpl
                    , private MethodTwoImpl
{
public:    
    using MethodOneImpl::method1;
    // Obviously this wouldn't work as the method names don't match.
    //using MethodTwoImpl::??? 
};

Первый оператор using сделает оба метода MethodOneImpl :: method1 общедоступными, но на самом деле он не выполняет контракт с Интерфейсом , и он изменяет доступность MethodOneImpl :: method1 (int) . И, очевидно, мы не могли использовать это решение с method2 , поскольку имена не совпадают.

FWIW, у меня есть то, что я считаю решением, но оно вообще не является частью стандарта (другими словами, оно не компилируется). Я подумывал внести предложение в комитет по C ++; Если у кого-то есть совет, я был бы признателен за любые комментарии ниже (но, пожалуйста, не отправляйте совет в качестве ответа).

8
задан Michael Price 14 November 2011 в 17:14
поделиться