Hi ROOT'ers,
I wanted to have a nested class Top::Nested that I could put in a
TClonesArray in the containing class Top. If there's a way to do
this, and I've somehow overlooked it, I'm sorry about this rather long
mail, and beesiege you to put it in the User's Guide (not in the one
from March 2001). If there's no way to do it, then I'll hope you'll
take a look at this mail (and attached example) and maybe use it if
you see fit.
However, coding away naiively like:
class Top : public TObject {
private:
int fN;
TClonesArray fArray;
public:
class Nested : public TObject {
private:
int fNested;
Nested(int nested=0) fNested(nested) {};
ClassDef(Nested, 1) // Nested class
};
Top() : fN(0), fArray("Top::Nested",0) {}
void AddNested(int a) { new(fArray[fN++]) Nested(a); }
Nested* GetNested(int i) { return (i >= fN || i < 0) ? 0 : fArray[i]; }
ClassDef(Top, 1) // Class with nested class
};
#pragma link C++ class Top+;
#pragma link C++ class Top::Nested+;
didn't go at all well. The problem is the friend declaration
friend TBuffer &operator>>(TBuffer &buf, Nested *&obj);
in the expansion of ClassDef(Nested). rootcint sees this as a friend
function called
TBuffer &Top::operator>>(TBuffer &buf, Top::Nested *&obj);
and makes a interface function for it, but G++ complains it can find
that function when compiling the dictionary files. Incidently, I
believe there's no way to implement a function like that. rootcint
creates
TBuffer &operator>>(TBuffer &buf, Top::Nested *&obj);
which is what you want, I believe. I'm not sure what is the correct
way to do it, in terms of the ANSI/ISO Standard. I looked it up, but
it wasn't clear to me what it said (Section 9.7, paragraph 4).
Someone more knowledgeable in the standard should investigate it.
Anyway, so I poked around, and found a hack that I believe works.
The trick is to define a macro ClassDef, and only have the troublesome
line
friend TBuffer &operator>>(TBuffer &buf, Nested *&obj);
in the expansion if __CINT__ is not defined, as is the case in
rootcint. Then I add an explicit external linkage declaration for
TBuffer &operator>>(TBuffer &buf, Top::Nested *&obj);
if __CINT__ _is_ defined, and explicitly in the linkdef file, tell
rootcint to create a interface function. Finally, I ask CINT to
make method/member interfaces for nested classes as well, by adding
the line
#pragma link C++ nestedclass;
in the linkdef file. This last thing _is_ documented, and _not_ part
of the hack.
Because I didn't get what the standard say about the naming scope of
friend functions declared in nested class, I don't know who's to blame
Masa or Rene and Fons :-)
I hope you'll find this usefull, at least as small hint to a possible
solution.
Yours,
Christian -----------------------------------------------------------
Holm Christensen Phone: (+45) 35 35 96 91
Sankt Hansgade 23, 1. th. Office: (+45) 353 25 305
DK-2200 Copenhagen N Web: www.nbi.dk/~cholm
Denmark Email: cholm@nbi.dk
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:44 MET