Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > using-declaration


Автор: iiizxc 2.3.2009, 16:55
Имеется следующий дизайн:
Код

class ISome
{
public:

    void someMethod1() {};
    void someMethod2() {};
};

class IAnother
{
public:

    void anotherMethod1() {};
};

class Object:
    public ISome,
    public IAnother
{
    using ISome::someMethod1;
    using ISome::someMethod2;
    using IAnother::anotherMethod1;
};

Объект Object является композицией имплементаций интерфейсов ISome и IAnother, однако сам как интерфейс не позволяет воспользоваться методами ISome и IAnother.
Код

Object object;

object.someMethod1(); // ERROR: cannot access private member

Тем не менее, Object позволяет перекастовать себя к интерфейсу ISome или IAnother (public наследование), и таким образом получить доступ к соответствующим методам.
Код

    Object object;

    ISome & some = static_cast< ISome & >( object );
    some.someMethod1();
    some.someMethod2();

    IAnother & another = static_cast< IAnother & >( object );
    another.anotherMethod1();


Проблема в том, что количество методов ISome или IAnother может быть большим и список этих методов может меняться.
Необходимо же все метоты и поля этих интерфейсов сделать private в Object. Так, объявление вроде
Код

class Object:
    public ISome,
    public IAnother
{
    using class ISome;
    using class IAnother;
};

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

Вопрос: можно ли все-таки как-то добиться желаемого?
Приватное наследование и перегрузка перекастовки - это не то.

Автор: Alek86 2.3.2009, 17:09
не делать Object наследником этих интерфейсов, а агрегировать их имплементации
при необходимости добавить или функции типа ISome* ToSome() или вообще операторы преобразования а-ля operator ISome&() (хотя особого смысла в операторе не вижу)

лучше всего сделать проксю
Код
class Helper:
    public ISome,
    public IAnother {};

class Object {
 ISome& ToSome() { return m_impl; }
 const ISome& ToSome() const { return m_impl; }
private:
 Helper m_impl;
};


Добавлено через 1 минуту и 50 секунд
но решение настолько корявое, что возникает вопрос - а зачем эти извращения нужны? в чем задача заключается?

Автор: iiizxc 2.3.2009, 17:19
Alek86, нет, агрегация с делегированием перекастовки - это тоже не то. Не спрашивайте, зачем это понадобилось smile

Автор: Alek86 2.3.2009, 17:42
чем именно не нравится?
(кстати, сложно отвечать на твой вопрос, не зная всей "обстановки")

имхо, в общем случае мой вариант получше кучи юзингов, которые не контролируются компилятором (то есть добавишь паблик в ISome - он молча появится в пабликах Object'а)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)