Re: A few simple C++ questions

From: Masaharu Goto (gotom@hpyiddq.jpn.hp.com)
Date: Mon Dec 22 1997 - 01:26:44 MET


Bill,

> I have two (basic) C++ questions I would like to present to any Guru in ROOT
> land.
> 
> (1):  How might I pass a public member function of class MYCLASS  into the
> constructor TF2?
> 
> class MYCLASS
> {
> Double_t MYCLASS::myfunction(Double_t *x, Double_t *y) { return
> x[0]*X[1]; };
> };
> 
> MYCLASS myclass;
> TF2 *tf2 = new TF2("name",  ???myclass.myfunction???, 0, 1, 0, 1);  // this
> doesn't work of course. Is there a way?

 It goes as follows.

 class MYCLASS {
  public:
   static Double_t myfunction(Double_t *x,Double_t *y) { 
     return x[0]*x[1]; 
   }
 };

  i) Scope specification to member function definition is only necessary
    when it is defined outside of class declaration. In this case, you
    define myfunction within class declaration.  Another way of doing the
    same thing is shown below. Below case defines myfunction outside of
    class declaration, then you need MYCLASS:: scope specification.

         class MYCLASS {
	   public:
            static Double_t myfunction(Double_t *x,Double_t *y) ; 
         };
         Double_t MYCLASS::myfunction(Double_t *x,Double_t *y) { 
           return x[0]*x[1]; 
         }

  ii) If you want to specify the function the same way as you do for global
     function, you must declare it as 'static'. Static member function is
     equivalent to global function. But ordinary member function has extra
     information which makes it incompatible with the global function.
     In this case, you are not using data member at all. So declaring
     myfunction as static is completely reasonable.


> (2): Is there a method in C++ to obtain member function resolution by return
> type?  For example
> 
> Double_t VECTOR::operator*(const VECTOR& rhs); // inner product
> VECTOR operator*(const VECTOR& rhs); // cross product
> MATRIX operator*(const VECTOR& rhs); // outer product
> 
> Double_t result;
> VECTOR v1, v2;
> result = v2*v2;  // this should use correct function based on return
> assignment.

 No, this is impossible. I recommend to use different operator or
 some explicit way of distinguishing inner/cross/outer products.

 I can think of an ugly trick to make your code work. But it is much more
 complicated than you would expect. Following code shows the concept.
 
  class VECTOR;
  class MATRIX;

  class XPRODUCT {  // a dummy product class which postpones actual 
    VECTOR *v1,*v2; // decision of inner/cross/outer product selection
   public:          // and calculation until point of assignment.
    friend class VECTOR;
    friend class MATRIX;
    operator Double_t() {            // assignment to Double_t
      return(innerproduct(*v1,*v2)); // use inner product
    } 
    XPRODUCT(VECTOR* v1in,VECTOR* v2in) : v1(v1in), v2(v2in) {}
  };

  class VECTOR { 
    // something here
   public:
    XPRODUCT operator*(VECTOR& v1,VECTOR& v2) {
      XPRODUCT xprod(&v1,&v2); // create dummy product obj to postpone
      return xprod;            // inner/outer/cross prod decision
    }
    VECTOR& operator=(XPRODUCT& x) {       // assignment to vector
      *this = crossproduct(*x.v1 , *x.v2); // use cross product
      return(*this);
    }
    Double_t innerproduct(VECTOR& v1,VECTOR& v2); // I do not show here
    VECTOR crossproduct(VECTOR& v1,VECTOR& v2);   // I do not show here
    MATRIX outerproduct(VECTOR& v1,VECTOR& v2);   // I do not show here
  };

  class MATRIX {
    // something here
    public:
     MATRIX& operator=(XPRODUCT& x) {      // assignment to matrix,
      *this = outerproduct(*x.v1 , *x.v2); // use outer product
      return(*this);
     }
  };

 Novice C++ programmer may want to stay away from this. Above method only
 works with only one operator per assignment, such as 'result=x*y'. You
 can not use combination of operators in one statement, like 'result=x*y*z'.
 If you want this also, you need to add another level of complication.

 Masaharu Goto



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:26:23 MET