Russian Qt Forum
Ноябрь 23, 2024, 03:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: определение операторов << \ >> для иерархии типов  (Прочитано 3462 раз)
unkeep
Гость
« : Август 08, 2014, 14:06 »

Есть Базовый класс (BaseObject). Нужно чтобы все его наследники поддерживали r\w операции в поток ( >> \ << ). Можно ли реализовать оператор на базовом классе, или только для каждого конкретного наследника?

Сделал так(код ниже). Работает. Но тогда эта реализация срабатывает и для типов неотнаследованных от BaseObject. что не есть хорошо((.

Код
C++ (Qt)
class BaseObject : public QObject
   {
       Q_OBJECT
   public:
       explicit BaseObject(QObject *parent = 0);
       virtual ~BaseObject();
 
       QString GetType();
       QString GetHash();
 
       virtual void Serialize(QDataStream &stream) const = 0;
       virtual void Deserialize(QDataStream &stream) = 0;
 
   };
   typedef QSharedPointer<BaseObject> BaseObjectShp;
 
   template<class T>
   inline QDataStream& operator <<(QDataStream& out, const QSharedPointer<T>& obj)
   {
       BaseObject* nullObj = static_cast<T*>(0);
       Q_UNUSED(nullObj );
 
       out << obj->GetType();
       obj->Serialize(out);
       return out;
   }
 
   template<class T>
   inline QDataStream& operator >>(QDataStream& in, QSharedPointer<T>& obj)
   {
 
       BaseObject* nullObj = static_cast<T*>(0);
       Q_UNUSED(nullObj );
 
       QString type;
       in >> type;
 
       if (obj.isNull())
       {
           FactoryShp factory = FactoryShp(new Factory);
           obj = qSharedPointerCast<T>(factory->Create(type));
       }
       obj->Deserialize(in);
       return in;
   }
 
« Последнее редактирование: Август 08, 2014, 14:11 от unkeep » Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #1 : Август 08, 2014, 23:27 »

Код:
struct Base
{
    virtual ~Config(){}
    virtual Str AboutMe()const =0;
    template<class T> friend T& operator<<(T& os, const Base& obj ){ os<<obj.AboutMe();  return os; }
};


struct Der:Base
{
    virtual ~Config(){}
    virtual Str AboutMe()const { return "trololo"; }
};
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Август 09, 2014, 10:03 »

Код:
struct Base
{
    virtual ~Config(){}
    virtual Str AboutMe()const =0;
    template<class T> friend T& operator<<(T& os, const Base& obj ){ os<<obj.AboutMe();  return os; }
};
Обычно есть цепочка записи/чтения потока, напр
Код
C++ (Qt)
os << mData1 << mData2 << mData3 << ...
Как это вписать в схему с virtual ? (отделаться одним AboutMe не удается)
« Последнее редактирование: Август 09, 2014, 10:22 от Igors » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #3 : Август 09, 2014, 10:18 »

Цитировать
отделаться одним AboutMe не удается
Это почему это не удаётся?
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Август 09, 2014, 10:23 »

Цитировать
отделаться одним AboutMe не удается
Это почему это не удаётся?
Потому что не видно что ему возвращать  Улыбающийся
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #5 : Август 09, 2014, 10:44 »

Цитировать
Потому что не видно что ему возвращать
В смысле, не видно?

Код
C++ (Qt)
struct base
{
   virtual ~base() {}
   virtual std::string msg() const = 0;
   template <class T>
   friend T& operator<<(T& os, const base & b) { os << b.msg(); return os; }
};
 
struct derived1 : public base
{
   virtual std::string msg() const { return "derived1"; }
};
 
struct derived2 : public base
{
   virtual std::string msg() const { return "derived2"; }
};
 
int main()
{
   derived1 d1;
   derived2 d2;
 
   std::cout << d1 << d2 << std::endl;
 
   return 0;
}
 

Другое дело, какой профит от такого решения..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Август 09, 2014, 18:27 »

Напр
Код
C++ (Qt)
struct CTest {
int a, b, c;
 
template <class stream>
friend stream & operator << (stream & os, const CTest & obj )
{
   os << a << b << c;  
   return os;
 }
};
Здесь stream может быть любым (текстовым, двоичным и.т.п.), были бы операторы << для int. Но здесь будут проблемы с классами наследниками т.к. << не виртуальный. Было бы круто вызвать виртуальную ф-цию из оператора, но она может вернуть только что-то одно (напр std::string)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.126 секунд. Запросов: 22.