Problem with branch class

Dear Rooters

Maybe this is a C++ question:
I have a class MyClass and its inherited class MySubClass which are both used for:
tree->Branch(“MyBranch”, “MySubClass”, &mysubclass);
tree->Branch(“MyBranch”, “MyClass”, &myclass);

Now I have a method Export() where I export the content of the trees to a file:

void Export()
{
   TTree *tree;
   MySubClass *myclass;

   tree->SetBranchAddress("MyBranch", &myclass);

   for (Int_t k=0; k<n; k++) {
      tree->GetEntry(i);

      output << sep << myclass->GetValue();
      if (hasSubValue) output << sep << myclass->GetSubValue();
   }
   output << endl;
}

Although this works in both cases, i.e the tree content is always exported to
a file, sorrowly, I get the following error message when I apply Export() to
a tree containing MyClass and not MySubClass:
Error in TTree::SetBranchAddress: The pointer type give (MySubClass) does not correspond to the class needed (MyClass) by the branch: MyBranch

The following workarounds do not work:

a, if (!hasSubValue) myclass = (MyClass*)myclass;
This causes a compiler error:
error: invalid conversion from ‘MyClass*’ to ‘MySubClass*’

b, if (hasSubValue) myclass = (MySubClass*)myclass;
This causes a compiler error:
error: ‘class MyClass’ has no member named ‘GetSubValue’

Does someone have an idea how I could solve this problem?

Thank you in advance
Best regards
Christian

[quote]Maybe this is a C++ question: [/quote]Indeed.

[quote]Error in TTree::SetBranchAddress: The pointer type give (MySubClass) does not correspond to the class needed (MyClass) by the branch: MyBranch
[/quote]is a correct message you can not use a MyClass as a MySubClass. But you can use a MySubClass as a MyClass. Hence you should be using:

[code]void Export()
{
TTree *tree;
MyClass *myclass;

tree->SetBranchAddress(“MyBranch”, &myclass);

for (Int_t k=0; k<n; k++) {
tree->GetEntry(i);

  output << sep << myclass->GetValue();

}
output << endl;
} [/code]And to deal with the different printout you should add a virtual function to MyClass and MySubClass which does the correct printing and use as:

[code]void Export()
{
TTree *tree;
MyClass *myclass;

tree->SetBranchAddress(“MyBranch”, &myclass);

for (Int_t k=0; k<n; k++) {
tree->GetEntry(i);
myclass.Output(output);
}
output << endl;
} [/code]

Cheers,
Philippe.

Dear Philippe

Thank you for your fast reply.
This is indeed an elegant solution and I will try to implement it.
However, I am not sure that it will be possible, since my real problem is more complex.
Another solution would be to have a virtual function:
myclass->GetValue(“mysubvalue”) which will always return the correct value.

Is there another solution which does not involve adding a virtual function to MyClass?

Best regards
Christian

[quote]Another solution would be to have a virtual function:
myclass->GetValue(“mysubvalue”) which will always return the correct value.
[/quote]I am a little confused … Why isn’t myclass->GetValue() sufficient (you would write MyClass::GetValue and MySubClass::GetValue)?

[quote]However, I am not sure that it will be possible, since my real problem is more complex.

Is there another solution which does not involve adding a virtual function to MyClass?
[/quote]It depends on what your real problem is! But unless you are trying to retrofit code you can not modify, adding a virtual function is the right solution (for what you described so far)!

Cheers,
Philippe.

The problem is that I am exporting the entries of few hundred trees as pivot table,
so I loop first over each tree and then over each of about hundredthousand
entries. For this reason the function should be fast. Probably I will do something like:

Double_t MySubClass::GetValue(Int_t id)
{return (id == 2) ? fVar2 : (id == 3) ? fVar3 : fVar1;}

Thank you
Christian

Hi Christian,

I still have too little information to know if this the best solution. Could you be more specific on your class layout?

Cheers,
Philippe.

Dear Philippe

It seems to be sufficient to stick to the example since the solution turned out to be simple:

void Export()
{
   TTree *tree;
   MyClass *myclass;

   tree->SetBranchAddress("MyBranch", &myclass);

   for (Int_t k=0; k<n; k++) {
      tree->GetEntry(i);

      output << sep << myclass->GetValue();
      if (hasSubValue) output << sep << (MySubClass*)myclass->GetSubValue();
   }
   output << endl;
}

Sorrowly, all the other solutions do not seem to work.

Thank you for your help and sorry for the confusion.

Best regards
Christian