By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,889 Members | 1,373 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,889 IT Pros & Developers. It's quick & easy.

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

P: n/a
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 MyDisplayFunctor:public 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 */
Jul 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a

"Jason" <JC********@hotmail.com> 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 MyDisplayFunctor:public 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::ostream& 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
Jul 22 '05 #2

P: n/a
"Jason" <JC********@hotmail.com> 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::ostream', 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 MyDisplayFunctor:public 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
Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.