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


Автор: XandoX 5.5.2006, 19:38
Здравствуйте!
Есть такое наследование:
ObjectData<-ObjectVisualInterface(он абстрактный)
ObjectData - хранит некоторые данные
ObjectVisualInterface - абстрактный класс определяющий интерфейс визуализации объекта, 
от него уже наследуются клссы визуализации для конкретных API (MFC, OpenGL, Win32)
И хотелось бы создать класс Object который хранит указатель на ObjectVisualInterface.
Но проблема в том, что ObjectVisualInterface содержит только функции обязательные, но конкретные реализации могут иметь еще и другие функции для своих нужд (например Устоновки цвета и т.д.)
и что бы использовать эти функции можно перегрузить operator-> который возвращает укозатель на нужный класс реализации интерфейса. Вопрос собственно в том как определить тип конкретной реализации и привести к нему ObjectVisualInterface*, или может можно как-нибуть его сохранить что бы потом использовать его?
Конечно можно было бы использовать шаблоны, но интересно: возможно ли такое без них?

 

Автор: bsa 5.5.2006, 19:59
Ищи документацию для:
http://www.cplusplus.com/doc/tutorial/typecasting.html
а лучше для dynamic_cast

например здесь: http://www.cplusplus.com 

Автор: XandoX 5.5.2006, 20:07
typid возврашает type_info, ето нельзя использовать как тип, а к dynamic_cast нужен конкретный тип, 
про что я собственно и спрашиваю. Дело в том что тип может быть создон познее, и не хочется переписывать код. 

Автор: MAKCim 5.5.2006, 21:20
Цитата

Вопрос собственно в том как определить тип конкретной реализации и привести к нему ObjectVisualInterface*

Это как раз легко если известны/ен производные/ый классы/с
точнее можно исп-ть typelists+dynamic_cast, как результат - индекс в списке типов нужного типа
вопрос в другом: в operator->() тип возвращаемого значения должен быть известен в compile-time, а здесь явно run-time 

Автор: XandoX 5.5.2006, 21:51
Цитата

вопрос в другом: в operator->() тип возвращаемого значения должен быть известен в compile-time, а здесь явно run-time  


тоесть без шаблонов не как?
а где про typelists почитать можно? 

Автор: MAKCim 5.5.2006, 21:56
Цитата

тоесть без шаблонов не как?

здается мне что и с шаблонами никак  smile 
про typelist-ы http://oz.by/books/more104640.html 

Автор: LuckLess 5.5.2006, 22:01
может так?
стиль аля COM
Код

#include <iostream>


class IVisual
   {
   public:
      virtual void QuerryInterface(int, void** retVal)
         {
         *retVal = 0;
         }
   };

class IExtendedVisual1 : public IVisual
   {
   public:
      virtual void QuerryInterface(int typeId, void** retVal)
         {
         if (typeId == 1)
            {
            IExtendedVisual1* rt(reinterpret_cast<IExtendedVisual1*>(*retVal));
            rt = this;
            }
         else
            {
            *retVal = 0;
            }
         }
   };

class IExtendedVisual2 : public IVisual
   {
   public:
      virtual void QuerryInterface(int typeId, void** retVal)
         {
         if (typeId == 2)
            {
            IExtendedVisual2* rt(reinterpret_cast<IExtendedVisual2*>(*retVal));
            rt = this;
            }
         else
            {
            *retVal = 0;
            }
         }
   };

class IExtendedVisual3 : public IVisual{};//класс не дает ничего нового по сравнению с базовым интерфейсом
//поэтому QuerryInterface не реализуеться.


void main(void)
   {
   IVisual* Interf = new IExtendedVisual1;
   IExtendedVisual1* ivis1;
   Interf->QuerryInterface(1, (void**)&ivis1);
   IExtendedVisual2* ivis2;
   Interf->QuerryInterface(2, (void**)&ivis2);   
   IExtendedVisual3* ivis3;
   Interf->QuerryInterface(3, (void**)&ivis3);
   std::cout << ivis1 << " " << ivis2 << " " << ivis3;
   }
 

Автор: MAKCim 5.5.2006, 22:09
Цитата

может так?

ИМХО, немного не то что просил XandoX
вообще, как хочет сделать он по-моему нельзя 

Автор: LuckLess 5.5.2006, 22:12
чуть более корректный вариант.
Код

#include <iostream>


class IVisual
   {
   public:
      virtual void QuerryInterface(int, void** retVal)
         {
         *retVal = 0;
         }
   };

class IExtendedVisual1 : public IVisual
   {
   public:
      virtual void QuerryInterface(int typeId, void** retVal)
         {
         if (typeId == 1)
            {
            IExtendedVisual1** rt = reinterpret_cast<IExtendedVisual1**>(retVal);
            *rt = this;
            }
         else
            {
            *retVal = 0;
            }
         }
   };

class IExtendedVisual2 : public IVisual
   {
   public:
      virtual void QuerryInterface(int typeId, void** retVal)
         {
         if (typeId == 2)
            {
            IExtendedVisual2** rt = reinterpret_cast<IExtendedVisual2**>(retVal);
            *rt = this;
            }
         else
            {
            *retVal = 0;
            }
         }
   };

class IExtendedVisual3 : public IVisual{};/*класс не дает ничего нового по сравнению с базовым интерфейсом*/
/*поэтому QuerryInterface не реализуеться.*/


void main(void)
   {
   IVisual* Interf = new IExtendedVisual1;
   IExtendedVisual1* ivis1;
   Interf->QuerryInterface(1, (void**)&ivis1);
   IExtendedVisual2* ivis2;
   Interf->QuerryInterface(2, (void**)&ivis2);   
   IExtendedVisual3* ivis3;
   Interf->QuerryInterface(3, (void**)&ivis3);
   std::cout << ivis1 << " " << ivis2 << " " << ivis3 << "\n";

   IVisual* Interf2= new IExtendedVisual2;
   Interf2->QuerryInterface(1, (void**)&ivis1);
   Interf2->QuerryInterface(2, (void**)&ivis2);   
   Interf2->QuerryInterface(3, (void**)&ivis3);
   std::cout << ivis1 << " " << ivis2 << " " << ivis3 << "\n";

   IVisual* Interf3= new IExtendedVisual3;
   Interf3->QuerryInterface(1, (void**)&ivis1);
   Interf3->QuerryInterface(2, (void**)&ivis2);   
   Interf3->QuerryInterface(3, (void**)&ivis3);
   std::cout << ivis1 << " " << ivis2 << " " << ivis3 << "\n";

   }


Добавлено @ 22:14 
Цитата(MAKCim @  5.5.2006,  22:09 Найти цитируемый пост)
ИМХО, немного не то что просил XandoX
вообще, как хочет сделать он по-моему нельзя  

тогда я не понял чего хочет автор.
ну operator нужный добавить е проблема.
что не то то? )) 

Автор: XandoX 6.5.2006, 07:44
Цитата

что не то то? ))

Дело в том, что я спрашивал про то можно ли как-нибуть динамически определить тип и использовать эти знание, что нибуть вроде typeid(я понимаю, что такого оператора нет), но только чтобы возвращал сам тип, а не информацию о нем.
Ты же предложил вариант, когда мне все ровно нужен указатель на реализацию интерфейса, с этим-то кокрас и проблема, так как я не знаю что там за реализация  smile 
Object строестя фабрикой для конкретной реализации, может можно в этот момент как-нибуть сохранить тип?
  

Автор: MAKCim 6.5.2006, 10:13
Цитата

что не то то? ))

судя по всему XandoX-у надо что-то типа
Код

class holder
{
private:
...
    abstract* ptr;
...
public:
    <тип указателя на на объект на который указывает ptr в действительности>* operator->() {return <что-то>;}
};

думаю в такой вариации это невозможно 

Автор: XandoX 6.5.2006, 10:24
MAKCim, ага именно, что-то типа.
Да я уже тоже до этого дошел, что не возможно. Спасибо за разэяснения 

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