Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Is this the right way to redirect output from a class to another?

Reply
Thread Tools

Is this the right way to redirect output from a class to another?

 
 
Jason
Guest
Posts: n/a
 
      08-23-2004
Hello,

I have a class, transCore, that does certain work, and by default, prints
its progress to the stand output.

Later, I will to write a GUI class that encapsulate the transCore class. I
would like to redirect/intercept the output of transCore class to this GUI
class. I wrote a sample program that demonstrate how I did it, but I am not
sure if it's any good. Can anyone critic my code? If there's any
non-standard conforming code or a better way to redirect output, please let
me know. Thank you.

/* program start */

#include<iostream>
#include<string>
using namespace std;
class BaseDisplayFunctor
{
private:
public:
virtual void print(const string &)=0;
};

template<class T>
class MyDisplayFunctorublic BaseDisplayFunctor
{
private:
//object pointer
T *object_ptr;
//function pointer to display
void (T::*func_ptr)(const string &);
public:
MyDisplayFunctor(T* obj, void (T::*Display)(const string&))
{
object_ptr = obj;
func_ptr = Display;
}
virtual void print(const string &s)
{
(*object_ptr.*func_ptr)(s);
}
~MyDisplayFunctor(){}
};
/*
Class: TRANSCORE

PURPOSE: this class will does all works and print progress to
the screen
*/
class TransCore
{
private:
BaseDisplayFunctor *BDF;
void print(const string& s)
{
if(BDF != NULL)
BDF->print(s);
else
cout<< s;
}
public:
TransCore(BaseDisplayFunctor *display){BDF = display;}
void dosomething()
{
print("does some work#1");
print("does some work#2");
}
~TransCore(){};
};
/*
Class: TEST

PURPOSE: Demonstrate how I would like to redirect simple output
*/
class Test
{
private:
TransCore *transCore;
MyDisplayFunctor<Test> *myDF;
void redirected_output(const string &s)
{
/*
Supposed to intercept whatever ouput from TRANSCORE to
a GUI display
*/
cout<<"Redirected: " <<s<<endl;
}

public:
Test()
{
myDF = new MyDisplayFunctor<Test>(this, &Test::redirected_output);
transCore = new TransCore(myDF);
transCore->dosomething();
}
~Test(){delete transCore; delete myDF;}
};

int main(int argc, char **argv)
{
Test wow;
system("pause"); //prevent windowXP from closing my console
return 0;
}

/* program end */


 
Reply With Quote
 
 
 
 
Mike Wahler
Guest
Posts: n/a
 
      08-24-2004

"Jason" <(E-Mail Removed)> wrote in message
news:eluWc.211$2F.144@trnddc05...
> Hello,
>
> I have a class, transCore, that does certain work, and by default, prints
> its progress to the stand output.
>
> Later, I will to write a GUI class that encapsulate the transCore class. I
> would like to redirect/intercept the output of transCore class to this GUI
> class. I wrote a sample program that demonstrate how I did it, but I am

not
> sure if it's any good. Can anyone critic my code? If there's any
> non-standard conforming code or a better way to redirect output, please

let
> me know. Thank you.
>
> /* program start */
>
> #include<iostream>
> #include<string>
> using namespace std;
> class BaseDisplayFunctor
> {
> private:
> public:
> virtual void print(const string &)=0;
> };
>
> template<class T>
> class MyDisplayFunctorublic BaseDisplayFunctor
> {
> private:
> //object pointer
> T *object_ptr;
> //function pointer to display
> void (T::*func_ptr)(const string &);
> public:
> MyDisplayFunctor(T* obj, void (T::*Display)(const string&))
> {
> object_ptr = obj;
> func_ptr = Display;
> }
> virtual void print(const string &s)
> {
> (*object_ptr.*func_ptr)(s);
> }
> ~MyDisplayFunctor(){}
> };
> /*
> Class: TRANSCORE
>
> PURPOSE: this class will does all works and print progress to
> the screen
> */
> class TransCore
> {
> private:
> BaseDisplayFunctor *BDF;
> void print(const string& s)
> {
> if(BDF != NULL)
> BDF->print(s);
> else
> cout<< s;
> }
> public:
> TransCore(BaseDisplayFunctor *display){BDF = display;}
> void dosomething()
> {
> print("does some work#1");
> print("does some work#2");
> }
> ~TransCore(){};
> };
> /*
> Class: TEST
>
> PURPOSE: Demonstrate how I would like to redirect simple output
> */
> class Test
> {
> private:
> TransCore *transCore;
> MyDisplayFunctor<Test> *myDF;
> void redirected_output(const string &s)
> {
> /*
> Supposed to intercept whatever ouput from TRANSCORE to
> a GUI display
> */
> cout<<"Redirected: " <<s<<endl;
> }
>
> public:
> Test()
> {
> myDF = new MyDisplayFunctor<Test>(this, &Test::redirected_output);
> transCore = new TransCore(myDF);
> transCore->dosomething();
> }
> ~Test(){delete transCore; delete myDF;}
> };
>
> int main(int argc, char **argv)
> {
> Test wow;
> system("pause"); //prevent windowXP from closing my console
> return 0;
> }
>
> /* program end */


#include <fstream>
#include <iostream>
#include <ostream>
#include <string>

void print(std:stream& os, const std::string& s)
{
os << s;
}

int main()
{
std::ifstream ifs("filename");
std::string s1("Hello");
print(std::cout, s1); // to standard output
print(ifs, s1); // to file
return 0;
}

-Mike


 
Reply With Quote
 
 
 
 
David Rubin
Guest
Posts: n/a
 
      08-24-2004
"Jason" <(E-Mail Removed)> wrote in message news:<eluWc.211$2F.144@trnddc05>...
> Hello,
>
> I have a class, transCore, that does certain work, and by default, prints
> its progress to the stand output.
>
> Later, I will to write a GUI class that encapsulate the transCore class. I
> would like to redirect/intercept the output of transCore class to this GUI
> class.


Two easy ways to do this are 1) have a 'setStream' function which
allows you to change the output stream from 'std::cout' (the default),
to some other 'std:stream', or 2) set the output stream in a
constructor.

> I wrote a sample program that demonstrate how I did it, but I am not
> sure if it's any good. Can anyone critic my code?


Sure.

[snip]
> #include<iostream>
> #include<string>
> using namespace std;
> class BaseDisplayFunctor
> {
> private:
> public:
> virtual void print(const string &)=0;
> };


This is not a functtor. AFAIK, "functor" is defined (largely) by the
presence of 'operator()'. In any case, inheritance is not the right
approach to solve your problem.

> template<class T>
> class MyDisplayFunctorublic BaseDisplayFunctor
> {
> private:
> //object pointer
> T *object_ptr;
> //function pointer to display
> void (T::*func_ptr)(const string &);
> public:
> MyDisplayFunctor(T* obj, void (T::*Display)(const string&))


This is just complicated. Pointers to functions are often helped by
typedefs.

> {
> object_ptr = obj;
> func_ptr = Display;


Your naming scheme is wildly inconsistent. Typically, people name data
members with a leading or trailing underscore, or a mnemonic, such as
'd_'. So this would be written as

d_obj_p = obj; // d_obj_p is a data member of a pointer type
d_func = func; // d_func is a function pointer (note, no '_p')

These conventions obviate the need for coming up with funny argument
names, and make the code much more readable.

> }
> virtual void print(const string &s)
> {
> (*object_ptr.*func_ptr)(s);


You can take advantage of a language feature which allows you treat
pointers to functions as functions when making function calls:

object_ptr->func_ptr(s);

> }
> ~MyDisplayFunctor(){}
> };
> /*
> Class: TRANSCORE
>
> PURPOSE: this class will does all works and print progress to
> the screen
> */
> class TransCore
> {
> private:
> BaseDisplayFunctor *BDF;
> void print(const string& s)
> {
> if(BDF != NULL)
> BDF->print(s);
> else
> cout<< s;


You should flush the stream with 'std::flush' or 'std::endl'.

> }
> public:
> TransCore(BaseDisplayFunctor *display){BDF = display;}
> void dosomething()
> {
> print("does some work#1");
> print("does some work#2");
> }
> ~TransCore(){};
> };
> /*
> Class: TEST
>
> PURPOSE: Demonstrate how I would like to redirect simple output
> */


Why is this a class? Just put all these mechanics into 'main'.

HTH, /david
 
Reply With Quote
 
Jason
Guest
Posts: n/a
 
      08-25-2004
Thank you, David. I'll rethink my approach on output redirection.



"David Rubin" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) m...
> "Jason" <(E-Mail Removed)> wrote in message

news:<eluWc.211$2F.144@trnddc05>...
> > Hello,
> >
> > I have a class, transCore, that does certain work, and by default,

prints
> > its progress to the stand output.
> >
> > Later, I will to write a GUI class that encapsulate the transCore class.

I
> > would like to redirect/intercept the output of transCore class to this

GUI
> > class.

>
> Two easy ways to do this are 1) have a 'setStream' function which
> allows you to change the output stream from 'std::cout' (the default),
> to some other 'std:stream', or 2) set the output stream in a
> constructor.
>
> > I wrote a sample program that demonstrate how I did it, but I am not
> > sure if it's any good. Can anyone critic my code?

>
> Sure.
>
> [snip]
> > #include<iostream>
> > #include<string>
> > using namespace std;
> > class BaseDisplayFunctor
> > {
> > private:
> > public:
> > virtual void print(const string &)=0;
> > };

>
> This is not a functtor. AFAIK, "functor" is defined (largely) by the
> presence of 'operator()'. In any case, inheritance is not the right
> approach to solve your problem.
>
> > template<class T>
> > class MyDisplayFunctorublic BaseDisplayFunctor
> > {
> > private:
> > //object pointer
> > T *object_ptr;
> > //function pointer to display
> > void (T::*func_ptr)(const string &);
> > public:
> > MyDisplayFunctor(T* obj, void (T::*Display)(const string&))

>
> This is just complicated. Pointers to functions are often helped by
> typedefs.
>
> > {
> > object_ptr = obj;
> > func_ptr = Display;

>
> Your naming scheme is wildly inconsistent. Typically, people name data
> members with a leading or trailing underscore, or a mnemonic, such as
> 'd_'. So this would be written as
>
> d_obj_p = obj; // d_obj_p is a data member of a pointer type
> d_func = func; // d_func is a function pointer (note, no '_p')
>
> These conventions obviate the need for coming up with funny argument
> names, and make the code much more readable.
>
> > }
> > virtual void print(const string &s)
> > {
> > (*object_ptr.*func_ptr)(s);

>
> You can take advantage of a language feature which allows you treat
> pointers to functions as functions when making function calls:
>
> object_ptr->func_ptr(s);
>
> > }
> > ~MyDisplayFunctor(){}
> > };
> > /*
> > Class: TRANSCORE
> >
> > PURPOSE: this class will does all works and print progress to
> > the screen
> > */
> > class TransCore
> > {
> > private:
> > BaseDisplayFunctor *BDF;
> > void print(const string& s)
> > {
> > if(BDF != NULL)
> > BDF->print(s);
> > else
> > cout<< s;

>
> You should flush the stream with 'std::flush' or 'std::endl'.
>
> > }
> > public:
> > TransCore(BaseDisplayFunctor *display){BDF = display;}
> > void dosomething()
> > {
> > print("does some work#1");
> > print("does some work#2");
> > }
> > ~TransCore(){};
> > };
> > /*
> > Class: TEST
> >
> > PURPOSE: Demonstrate how I would like to redirect simple output
> > */

>
> Why is this a class? Just put all these mechanics into 'main'.
>
> HTH, /david



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Response.redirect does not redirect from .aspx page =?Utf-8?B?VHJveQ==?= ASP .Net 3 10-15-2008 09:07 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
Redirect to secure FTP site via response.redirect Ron Howard ASP General 2 08-11-2004 07:40 PM
Basic Q - Response.Redirect, all redirect to first Response.Redirect statement Sal ASP .Net Web Controls 1 05-15-2004 03:46 PM
The right way to Encode html output ViperDK ASP .Net 2 07-22-2003 07:14 PM



Advertisments