Динамический полиморфизм без указателей на базовый класс.

Тема в разделе "LANGS.C", создана пользователем Antolflash, 31 май 2011.

  1. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Есть в моём C++ коде абстрактный класс, в котором есть только методы (т.е. это интерфейс). И среди этих методов я хочу, чтобы были операторы +, *, =, причём все они принимают и возвращают реальные объекты, а не указатели на базовый класс! Подобное реализуемо? Я просто хочу сделать единый интерфейс, и от него унаследовать разные реализации, чтобы можно было легко перекомпилировать с разными реализациями. Этому мешает тот факт, что я не могу указать компилятору, что принимается/возвращается объект-наследник. Нет, можно сделать аргументами операторов указатели на базовый класс, но это совсем не наглядно, ведь операторы в привычном представлении проводят действия с объектами, а не с адрессами.
    Т.е. интерфейс может работать только с типом "указатель на интерфейс", и домысливать реальные объекты-наследники он не может?
     
  2. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Код (Text):
    1. #pragma pack(1)
    2. struct basewad
    3. {
    4.     virtual bool GetEdge() = 0;
    5.     virtual bool GetMark() = 0;
    6.     virtual bool GetColour_0() = 0;
    7.     virtual bool GetColour_1() = 0;
    8.     virtual void SetEdge(bool what) = 0;
    9.     virtual void SetMark(bool what) = 0;
    10.     virtual void SetColour_0(bool what) = 0;
    11.     virtual void SetColour_1(bool what) = 0;
    12.     /*virtual basewad &operator+(basewad &op2) = 0;
    13.     virtual basewad &operator+=(basewad &op2) = 0;
    14.     virtual basewad &operator=(basewad &op2) = 0;
    15.     virtual basewad &operator=(bool edge) = 0;
    16.     virtual bool operator==(bool isedge) = 0;
    17.     virtual basewad &operator*(basewad &op2) = 0;*/
    18.     virtual operator bool() = 0;
    19. };
    20.  
    21. #pragma pack(1)
    22. struct field : public basewad
    23. {
    24.     unsigned Edge : 1;
    25.     unsigned Mark : 1;
    26.     unsigned Colour_1 : 1;
    27.     unsigned Colour_0 : 1;
    28.     bool GetEdge();
    29.     bool GetMark();
    30.     bool GetColour_0();
    31.     bool GetColour_1();
    32.     void SetEdge(bool what);
    33.     void SetMark(bool what);
    34.     void SetColour_0(bool what);
    35.     void SetColour_1(bool what);
    36.     field &operator=(field &op2);
    37.     field &operator=(bool edge);
    38.     field &operator+=(field &op2);
    39.     field &operator*(field &op2);
    40.     field &operator+(field &op2);
    41.     bool operator==(bool isedge);
    42.     operator bool();
    43.     field();
    44. };
     
  3. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Кусок с операторами закомментирован, т.к. операторы интерфейса нереализуемы.
     
  4. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Antolflash
    Я ничего не понял. Раскоментируй операторы. В чем проблема? Ты хочешь чтобы перегрузка функций и операторов работала с учетом динамического типа?

    Британский английский в коде - дурной тон :)
     
  5. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Думаю мультиметоды должны помочь, хотя их реализация на С++ немного кривая.
     
  6. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    _DEN_
    Как только я раскомментирую операторы, класс field превратится в абстрактный! Ведь операторы класса field возвращают реальные объекты field! А операторы внутри интерфейса существовать полноценно не могут, ведь как принять объект нереализуемого класса, можно принять указатель на интерфейс, но не объект интерфейса, ведь такого не существует.

    Британский английский - мой любимый, сказываются 10 лет спец.школы, в которой учили английскому английскому, и куча произведений Эдгара По (хоть он и американец, но писал он на очень английском английском) и Сомерсета Мома.

    Мультиметоды... ё-маё, сколько всего я вообще не знаю.
    Я почитал, как я понял, все аргументы объявляются виртуальными, и в зависимости от типа аргумента (и от типа указателя this, который тоже как-бы аргумент) делается выбор метода.

    Но они ещё вообще не реализованны!
    Ладно, забью на этот интерфейс, а просто создам разные классы реализации. Да, тут уже не видно, какие функции обязательны к реализации, а какие - частности самого класса, но что уж, мне работу надо доделывать, время жмёт.
     
  7. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Т.е. если интерфейс предполагает наличие у наследника операторов, принимающих или возвращающих обекты-наследники, то такой интерфейс просто нельзя написать. Ведь нельзя ввести в интерфейс тип "любой наследник".
    Т.е. внутри интерфейса невозможна конструкция
    Код (Text):
    1. любой_тип_наследник operator+(любой_тип_наследник &op2)
    Обидно.
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Любой это и есть базовый. Ну а если ты про мультитметоды, то С++ их не поддерживает, приходится писать костыли.
     
  9. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Antolflash

    Твоя интуиция, судя по всему, воспитана каким-то другим языком, вроде явы или шарпа. В C++ нет такого языкового понятия как "интерфейс" или "абстрактный класс". В C++ эти понятия есть только в разговорно-бытовом общении. Есть указатель, но нет объекта? Это как? Указатель всегда указывает на объект. Указатель - это просто уровень косвенности, а объект есть всегда (ну не считая bad pointer).

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

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Booster Меня понял.
    _DEN_
    Ок, поясню. Есть нереализуемые классы. Таковыми становятся базовые классы с чисто виртуальными функциями, либо их наследники, которые не реализовали хотя-бы одну из этих чисто-виртуальных функций.
    Такие классы я буду звать абстрактными.

    Так вот, нереализуемый класс (т.е. абстрактный), состоящий только из чисто-виртуальных функций интерфейсом, буду звать интерфейсом.


    Моя главная мысль:
    В интерфейсе не может быть операторов, которые принимают\возвращают объекты!!!

    Можно оперировать указателями базового типа, но оперировать несуществующими базовыми объектами нельзя!
     
  11. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    А проблемы в этом нет, я просто обнаружил пробел в языке, из-за которого мне пришлось чуток переписать код.
    И это только для того, чтобы наследование интерфейса автоматически значило корректность дальнейшего применения наследника.
     
  12. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Antolflash

    Я так понимаю, что ты хочешь сказать, что операторы-то можно сделать, но использовать их не получится, потому что не получится инстанцировать объект класса, в котором есть чисто виртуальные функции. Это не так :) Ссылки за тем и были введены в язык, чтобы и косвенность сохранить, и операторы работали.

    Код (Text):
    1. class abstract
    2. {
    3. public:
    4.  
    5.     virtual abstract& operator += (int value) = 0;
    6. };
    7.  
    8. abstract* create();
    9.  
    10. int main()
    11. {
    12.     abstract* ptr = create();
    13.     abstract& ref = *ptr;
    14.  
    15.     ref += 10; // Та-даммммм!
    16.  
    17.     return 0;
    18. }
     
  13. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Antolflash
    Побойся Саттера делать такие утверждения :)))
     
  14. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Antolflash
    Их полно.
     
  15. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Booster
    Лол, даже не начинай, мне уже смешно ))
     
  16. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Ну чтож я рад, что удалось поднять настроение.
     
  17. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Antolflash
    Почему это нельзя?
    Пожалуйста:

    Код (Text):
    1.     class Impl;
    2.     class Interface
    3.     {
    4.     public:
    5.         virtual Impl & operator +(Impl const &) = 0;
    6.     };
    7.  
    8.     //...
    9.     class Impl : Interface
    10.     {
    11.     public:
    12.         Impl & operator +(Impl const &)
    13.         {
    14.             return *this;
    15.         }
    16.     };
    Правда, непонятно, зачем понадобился такой изврат...
     
  18. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    green
    А если еще будет Impl2 от интерфейса?

    Antolflash
    Посмотрите какую чудную магию умеют делать шаблоны ... :)
     
  19. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    shchetinin
    Ну и пусть. :)
     
  20. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    green

    Если я понял автора, то он хочет чтобы оператор срабатывал над чем-то, что видно как Interface, а не как Impl.