Re: Base class method

From: Victor Perevoztchikov (perev@bnl.gov)
Date: Wed Nov 24 1999 - 19:43:15 MET


Dear Masaharu,
> Dictionary size is already too big. I think it is better not doing
> about change.

I agree, that it is too much to increase already big dictionary.
I was asking really about workaround. But it is probably too complicated.
Actually I need it only for Streamer() but even for this only it is too much

I tried to find workaround in C++ but also failed.

In plain g++ i found

   TNamed tm("AAA","BBB")

   tm.TObject::Getname(); //gives "TNamed" which is correct
   but

   char *(TNamed::gn)();
   gn = &TNamed::TObject::Getname;
   (tm.*gn)();             //gives "AAA"  which is wrong

Thank you,
Victor



Masaharu Goto wrote:
> 
> Dear Victor,
> 
> Thank you for reporting this problem. I found out the cause. The
> problem occurs when you call a virtual function of a precompiled class
> with scope operator. Unfortunately, this one will be left as it is.
> Here is the reason.
> 
> This is deeply related to dictionary operation. Cint is calling
> wrapper function for TObject::GetName, but because it is a virtual
> function, it ends up calling TNamed::GetName. I will explain in a simple
> source.
> 
>   // user header ////////////////////////////////////////////
>   class A {
>    public:
>     virtual const char* GetName() const { return("base"); }
>   };
>   class B : public A {
>    public:
>     const char* GetName() const { return("derived"); }
>   };
> 
> If you do makecint or rootcint on this header, dictionary would look like
> below.
> 
>   // dictionary /////////////////////////////////////////////
>   static int G__A_GetName_0_0( .... ) {
>      ...
>     const char* result = ((A*)obj)->GetName(); // virtual function call
>      ...
>   }
> 
>   static int G__B_GetName_0_0( .... ) {
>      ....
>     const char *result = ((B*)obj)->GetName(); // virtual function call
>      ....
>   }
> 
> Cint calls  G__B_GetName_0_0 for tn->GetName() and G__A_GetName_0_0
> for tn->TObject::GetName(). However, because A::GetName is a
> virtual function, it resolves to B::GetName(). As cint distinguishes
> two cases correctly, it is technically possible to solve this problem.
> Problem is that we have to almost doulbe the dictionary size.
> Every virtual function, we have to have virtual and non-virtual wrappers.
> 
>   // dictionary /////////////////////////////////////////////
>   static int G__A_GetName_0_0( .... ) {
>      ...
>     const char* result = ((A*)obj)->GetName(); // virtual function call
>      ...
>   }
>   static int G__B_GetName_0_0( .... ) {
>      ....
>     const char *result = ((B*)obj)->GetName(); // virtual function call
>      ....
>   }
>   static int G__A_GetName_0_0_nonvirtual( .... ) {
>      ...
>     const char* result = ((A*)obj)->A::GetName(); // non virtual
>      ...
>   }
> 
>   static int G__B_GetName_0_0_nonvirtual( .... ) {
>      ....
>     const char *result = ((B*)obj)->B::GetName(); // non virtual
>      ....
>   }
> 
> Dictionary size is already too big. I think it is better not doing
> about change.
> 
> Thank you
> Masaharu Goto
> 
> >Dear Masaharu,
> >
> >I found some discrepancy between CINT and C++
> >
> >
> >root [2] tn = new TNamed("AAA","BBB")
> >root [3] tn->GetName()
> >(Text_t* 0x85eb55c)"AAA"       // It is correct
> >root [4] tn->TObject::GetName()
> >(Text_t* 0x85eb55c)"AAA"       // It is incorrect
> >
> >C++ gives
> > AAA for first case;
> > TNamed for second;
> >
> >Is it hard to fix, or may be there is some workaround?
> >
> >Generally I need to call method of base class in CINT or by
> >G__ClassInfo family.
> >
> >Victor
> >
> >--
> >Victor M. Perevoztchikov   perev@bnl.gov  perev@vxcern.cern.ch
> >Brookhaven National Laboratory MS 510A PO Box 5000 Upton NY 11973-5000
> >tel office : 631-344-7894; fax 631-344-4206; home 631-345-2690

-- 
Victor M. Perevoztchikov   perev@bnl.gov  perev@vxcern.cern.ch       
Brookhaven National Laboratory MS 510A PO Box 5000 Upton NY 11973-5000
tel office : 631-344-7894; fax 631-344-4206; home 631-345-2690



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