0

I'm trying to figure out how to attach a class with pure virtual <</>> operators to other classes for the purpose of saving/loading the application state.

So I started off with:

class IWriteable  
{
public:
	IWriteable(): pCls(NULL) {}
	IWriteable(void *p): pCls(p) {}
	virtual ostream& operator << (const void * &p) = 0;
	virtual istream& operator >> (const void * &p) = 0;

protected:
	void *pCls;

};

This probably would've worked fine, but then there's that annoying void pointer that I should "never use." But the idea here would be to initialize pCls with a pointer to the derived class and cast accordingly to access the derived class' members.

Since I should "never use" them. I switched over to a template implementation but now I come across an area that I'm unfamiliar with the templates. Normally I just add the function definitions underneath the template class declaration (as I always get errors if I try to put them in a .cpp file). But I can't really do that now.... at least I don't think I can as I'll get a circular reference going on between the header file of the derived class. Unless there's something I'm not doing right...... which is a decent possibility.

Template Implementation:

//Writeable.h
template <typename T> class IWriteable  
{
public:
	IWriteable() {}
	virtual ostream& operator << (const T &p) = 0;
	virtual istream& operator >> (const T &p) = 0;
};

//Order.h
class COrder : public IWriteable<COrder>
{
public:
	COrder() {::memset(this,0,sizeof(*this));}
	//Link to trades from OrderSlates

	int			iOrderNumber;
	time_t		tOpen;
	time_t		tClose;
	int			iOrderType;
	double		dLots;
	string		szSymbol;
	double		dOpenPrice;
	double		dSL;
	double		dTP;
	double		dClosePrice;
	double		dSlippage;
	double		dSwap;
	double		dCommission;
	double		dProfit;
};

ostream& IWriteable<COrder>::operator << (const COrder &p) {
}

ostream& IWriteable<COrder>::operator >> (const COrder &p) {
}

If I put in the ostream &os/istream &is parameters the compiler came back at me with "Too many parameters." I don't know if my choice was correct in the single parameter. But above gives me a bunch of errors (aside from no return type), function redefinitions (order.h(42) : error C2371: '>>' : redefinition; different basic types), pure virtual function can't be used (but I want this.... I'll explain), etc.

The goal here aside from just saving/loading is to:

  • Force me to implement the <</>> operators for different classes I want. My brain has become like swiss cheese so having the compiler tell me I forgot to implement these as a reminder is a quick way for me to fix it.
  • All the overrides will be better organized in the class browser control.
  • Easier to maintain.

I'm going to pursue the void pointer method for now just to get something working but I prefer to use templates if it's possible. Is it? Or does a better solution exist?

I have a basic stream question too that has been bugging me on and off for years. What I usually end up doing is not using streams (which is why I don't know too much about streams)

Is there anyway to use <</>> to write binary unformatted data to a stream? Some flag I haven't seen yet? Manipulator?...... I think my brain finally kicked in.... reinterpret_cast to char (w/i the operator overload) and write that to stream? But then the problem would be the functions don't have different declarations? (i.e. ostream& operator << (ostream& os, float) already exists :/ )

Or did I overlook something?

Thanks for your help.

3
Contributors
3
Replies
4
Views
7 Years
Discussion Span
Last Post by nrobidoux
0

Welcome nrobidoux,
I have try to answer the following question.

I'm trying to figure out how to attach a class with pure virtual <</>> operators to other classes for the purpose of saving/loading the application state.

Overload a << (insertor) method; it must be friend. Insertor operator method requires two arguments. An object is supposed to be at left of << operator.

cout << obj; // Yes
 obj << cout; // No

Here is code that demonstrate how to overload an insertor operator and print state of entire hierarchy of classes.

#include <iostream>

class Base {
 public:
   friend std::ostream& operator<< (std::ostream& refobj, const Base& b);
 protected:
   virtual void print(std::ostream& refobj) const = 0;
};

inline std::ostream& operator<< (std::ostream& refobj, const Base& b)
{
   b.print(refobj);
   return refobj;
 }

class Derived1 : public Base {
 public:
 protected:
   virtual void print(std::ostream& o) const
   {
       std::cout << "\nDerived1";
   }
};

class Derived2 : public Base {
 public:
 protected:
   virtual void print(std::ostream& o) const
   {
       std::cout << "\nDerived2";
   }
};
int main(){
 Derived1 a;
 Derived2 b;
 std::cout << a << " " << b;
 return 0;
}
0
COrder() {::memset(this,0,sizeof(*this));}

I really hope that you know what you are doing here....

0

Works fine as long as no virtual functions are used in the current or base classes. Which was the case originally before I wanted to add this <</>> base class to it..... If any virtual pointers are present it sets the virtual pointer to 0 which results in disaster :)

Which would've been apparent pretty quickly if I ever got it to compile.

Thanks adatapost, works like a charm.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.