468,548 Members | 1,868 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,548 developers. It's quick & easy.

Interfaces and generic templates

(To the extent that this is a rehash of earlier questions, sorry.)

I feel like I'm starting to get the hang of how to make classes work
with << and >>, so now I have the (possibly dumb) idea to create
generic interfaces that use these, making it easy to subclass our
existing classes and make them behave a little better in the C++
world. I'm going to describe what I'm doing in some detail - feel
free to interject criticism at any point, since I'm not at all sure
what can be done better...

To start with: Create a class/interface Receivable that serves to
buffer data written to it (currently, a lot of code we have takes only
const char *'s for writing):

class Receivable // Buffered line input via <<
{
protected:
std::ostringstream outbuf;

public:
virtual void ProcessInput( std::string& s )=0;

template <class T> void Buffer( const T& t );
template <class T> Receivable& operator<< ( const T& t );
void Flush() {ProcessInput(outbuf.str()+"\n");}
};

template <class T> void Receivable::Buffer( const T& t )
{
outbuf << t;
std::string& buf=outbuf.str();
if( buf[buf.length()-1]=='\n' ) {
ProcessInput( buf );
}
outbuf.clear();
outbuf.str( "" );
}

template <class T> Receivable& Receivable::operator<< ( const T& t )
{
Buffer( t );
return( *this );
}

Okay, great, maybe. Now create an interface Stringizable that allows
classes that implement it to appear on the right side of << operators:

class Stringizable
{
virtual const char* ToString()=0; // returns const char * because
// that's what a lot of code
// already returns
};

Uh-huh, you say. But how to make Stringizables work with the <<
operator? Maybe

template <class T>
T& __fastcall operator<< ( const T& t, const Stringizable& s )
{
t << s.ToString();
return( t );
}

Fine and dandy, as long as T doesn't implement Stringizable, eh? How
can I make it that general? But onward - now I should be able to put
these interfaces to work in my previously-mentioned TLSFileStream
class:

class
TLSFileStream : public TLSFile, public Receivable, public Stringizable
{
typedef TLSFile Inherited;

public:
CPCHAR __fastcall ToString() {return(AsString());} // TLSFile
void __fastcall ProcessInput( std::string& s )
{
Inherited::Write( s.c_str() ); // implemented by TLSFile
}
~TLSFileStream() {Flush();}
};

So theoretically, I should be able to do

TLSFileStream fs1, fs2;
....
fs1 << fs2;

But, as I noted above, TLSFileStream implements both interfaces, and
thus the compiler can't figure it out.

Help/suggestions, please :)

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #1
0 879

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by gong | last post: by
11 posts views Thread by Steven T. Hatton | last post: by
4 posts views Thread by Leslaw Bieniasz | last post: by
42 posts views Thread by redefined.horizons | last post: by
18 posts views Thread by Tony | last post: by
3 posts views Thread by Johs | last post: by
reply views Thread by NPC403 | last post: by
1 post views Thread by UniDue | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.