Russian Qt Forum

Программирование => С/C++ => Тема начата: unkeep от Август 08, 2014, 14:06



Название: определение операторов << \ >> для иерархии типов
Отправлено: 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;
   }
 


Название: Re: определение операторов << \ >> для иерархии типов
Отправлено: _Bers от Август 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"; }
};


Название: Re: определение операторов << \ >> для иерархии типов
Отправлено: Igors от Август 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 не удается)


Название: Re: определение операторов << \ >> для иерархии типов
Отправлено: m_ax от Август 09, 2014, 10:18
Цитировать
отделаться одним AboutMe не удается
Это почему это не удаётся?


Название: Re: определение операторов << \ >> для иерархии типов
Отправлено: Igors от Август 09, 2014, 10:23
Цитировать
отделаться одним AboutMe не удается
Это почему это не удаётся?
Потому что не видно что ему возвращать  :)


Название: Re: определение операторов << \ >> для иерархии типов
Отправлено: m_ax от Август 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;
}
 

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


Название: Re: определение операторов << \ >> для иерархии типов
Отправлено: Igors от Август 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)