Re: [ROOT] General questions

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Fri Dec 07 2001 - 17:51:53 MET


Hi Matt, 

On Fri, 7 Dec 2001 12:28:42 +0000
Matt Palmer <palmer@hep.phy.cam.ac.uk> wrote
concerning "[ROOT] General questions":

> 2.  I made a simple little 3D viewer for some of my data (which was  
> impressively easy :) ).  However, I use TPolyLine3D to do the
> drawing and I can't get any of the lines to be drawn in different
> colours.   Currently I do  something like:
> 	TPolyLine3D* beamaxis = new TPolyLine3D(2);
> 	beamaxis->SetPoint(0, 1000, 1000, 0);
> 	beamaxis->SetPoint(1, 1000, 1000, 2000);
> 	gStyle->SetLineColor(2);
> 	beamaxis->UseCurrentStyle();
> 	beamaxis->Draw();

Use TPolyLine3D::SetLinecolor(Color_t); 

> As a general point tho, I think I am right in saying that multiple
> inheritance of non-pure virtual classes (ie non-interfaces) in
> object hierachies with a single shared parent base class (ie
> TObject) cannot work ...that's why it isn't allowed in Java, .NET
> etc

It will work if you have _virtual_ inheritance!  See also the ANSI/ISO
C++ standard chapter 10.  Suppose you have 

  #include <iostream>
  #ifdef USE_VIRTUAL 
  #define VIRTUAL virtual 
  #else 
  #define VIRTUAL
  #endif
  
  class A { 
    public:  virtual void f() { cout << "A:f" << endl; }}; 

  class B : VIRTUAL public A { 
  #ifdef USE_OVERLOAD
    public: virtual void f() { cout << "B::f" << endl; }
  #endif
  };

  class C : VIRTUAL public A  { 
  #ifdef USE_OVERLOAD
    public: virtual void f() { cout << "C::f" << endl; }
  #endif
  };
 
  class D : public B, public C { }; 

  int main() 
  {
    D d;
    d.f();
    return 0;
  }

With USE_VIRTUAL undefined, it will not work, since you cannot find a
unique calling sequence to A::f  

      A       A
       \     /
        B   C
         \ /
          D

Compiling with GCC like 

  prompt% g++ foo.cxx -o foo 
  foo.cxx: In function `int main()':
  foo.cxx:28: request for method `f' is ambiguous
  
On the other hand, if we do define USE_VIRTUAL, it will work. 

  prompt% g++ foo.cxx -o foo -DUSE_VIRTUAL 
  prompt% ./foo
  A:f

This is because we now have for A::f

          A 
         / \
        B   C
         \ /
          D

Now, if we define USE_OVERLOAD, then we get into trouble again: 

  prompt% g++ foo.cxx -o foo -DUSE_VIRTUAL -DUSE_OVERLOAD   
  foo.cxx: In function `int main()':
  foo.cxx:27: cannot declare variable `d' to be of type `D'
  foo.cxx:27:   since the following virtual functions need a final overrider:
  foo.cxx:27: 	void B::f()
  foo.cxx:28: request for method `f' is ambiguous

So it seems C++ fares better than Java and .NET :-). Now, wether this
would be a good strategy for ROOT classes to follow is an entirely
different matter. 

Yours, 

Christian Holm Christensen -------------------------------------------
Address: Sankt Hansgade 23, 1. th.           Phone:  (+45) 35 35 96 91 
         DK-2200 Copenhagen N                Cell:   (+45) 28 82 16 23
         Denmark                             Office: (+45) 353  25 305 
Email:   cholm@nbi.dk                        Web:    www.nbi.dk/~cholm



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:51:11 MET