| re: Is this the right way to redirect output from a class to another?
"Jason" <JC20032344@hotmail.com> wrote in message news:<eluWc.211$2F.144@trnddc05>...[color=blue]
> 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.[/color]
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.
[color=blue]
> 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?[/color]
Sure.
[snip][color=blue]
> #include<iostream>
> #include<string>
> using namespace std;
> class BaseDisplayFunctor
> {
> private:
> public:
> virtual void print(const string &)=0;
> };[/color]
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.
[color=blue]
> 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&))[/color]
This is just complicated. Pointers to functions are often helped by
typedefs.
[color=blue]
> {
> object_ptr = obj;
> func_ptr = Display;[/color]
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.
[color=blue]
> }
> virtual void print(const string &s)
> {
> (*object_ptr.*func_ptr)(s);[/color]
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);
[color=blue]
> }
> ~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;[/color]
You should flush the stream with 'std::flush' or 'std::endl'.
[color=blue]
> }
> 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
> */[/color]
Why is this a class? Just put all these mechanics into 'main'.
HTH, /david |