Question regarding multiple inheritance

Dear Rooters

I have a question regarding the use of multiple inheritance, as shown in the following code fragment:

class XProject: public TNamed {

   public:
      XProject();
      XProject(const char *name, const char *title);
      virtual ~XProject();

      virtual void AuthorInfo(const char *lastname, const char *firstname);
};

class XManager: public TNamed, public XProject {

//??   friend class XProject;

   protected:
      TList  *fList; 

   public:
      XManager();
      XManager(const char *name, const char *title);
      virtual ~XManager();

      virtual void New(const char *name);
};

void XProject::AuthorInfo(const char *lastname, const char *firstname)
{
   XAuthorInfo *info = new XAuthorInfo(lastname, firstname);

   fList->Add(info);
}

void MacroProject()
{
   XManager *manager = new XManager("DataManager");

   manager->New("MyProject");
   manager->AuthorInfo("LastName","FirstName");

   delete manager;
}

The function to be called from root is macro MacroProject() where “manager->AuthorInfo()” is called to fill fList.
The problem is that fList is defined in class XManager, but I need to fill the list in function AuthorInfo() of class XProject.
Obviously this does not work, even when defining friend class XProject.

Is there a way or trick in C++ how to handle this case?

Thank you in advance.
Best regards
Christian

I suppose that this should work:

[code]class XProject: public TNamed {

protected:
XAuthorInfo *CreateAuthorInfo(const char *lastname, const char *firtname);

public:
XProject();
XProject(const char *name, const char *title);
virtual ~XProject();

  virtual void AuthorInfo(const char *lastname, const char *firstname);

};

class XManager: public TNamed, public XProject {

protected:
TList *fList;

public:
XManager();
XManager(const char *name, const char *title);
virtual ~XManager();

  virtual void AuthorInfo(const char *lastname, const char *firstname);
  virtual void New(const char *name);

};

XAuthorInfo *XProject::CreateAuthorInfo(const char *lastname, const char *firstname)
{
return new XAuthorInfo(lastname, firstname);
}

void XManager::AuthorInfo(const char *lastname, const char *firstname)
{
XAuthorInfo *info = CreateAuthorInfo(lastname, firstname);

fList->Add(info);
}

void MacroProject()
{
XManager *manager = new XManager(“DataManager”);

manager->New(“MyProject”);
manager->AuthorInfo(“LastName”,“FirstName”);

delete manager;
} [/code]Aka overload AuthorInfo in XManager.

Cheers,
Philippe

Dear Philippe

Thank you for your suggestion, however for this case I did not need to create class XProject:
In my current code I have the same methods in two subclasses of XManager, e.g.:

XDataManger::AuthorInfo()
XDataManger::ProjectInfo()
XDataManger::DatasetInfo()
etc

XProcessManger::AuthorInfo()
XProcessManger::ProjectInfo()
XProcessManger::DatasetInfo()
etc

Since XDataManger is not inherited from XProcessManger, I am now trying to move the corresponding
methods to a new class XProject, and use multiple inheritance (which until now I tried to avoid).
Maybe you know a different option.

I thought that by declaring friend I could access fList also from XProject, but this seems not to be possible.
Lookng at you suggestion I found that there may be three options:

  • declare "XAuthorInfo *fAuthorInfo in XProject (as you seem to suggest) and fill fList from within XManager
  • declare “static TList *fList” to allow access to XManager::fList from XProject (which is not elegant)
  • use a separate list for each base class and define a function to fill one list with the content of the other list.
    Maybe you know some other options.

Best regards
Christian

[quote]In my current code I have the same methods in two subclasses of XManager,[/quote]Why not move the method into XManager then?
I think I am missing a couple of essential details (what are the relation ship between the classes, why do you want to move the methods, etc.) to be of more help :slight_smile:. A complete example as well as a good description of the ‘feature’ you are trying to add would let me understand of a bit better.

Cheers,
Philippe

Dear Philippe

Sorry, I know that a lot of information is mising, e.g. I do not want to move these methods to XManager,
since XManager is a general class, which can be used independently of the current application.
If you are really interested, you can download my program from: bioconductor.org/packages/2.2/bioc/html/xps.html
You do not need to install R, you can compile the library w/o R. A description of the program can be found at:
ci.tuwien.ac.at/Conferences/ … ratowa.pdf
My intention is to store database information in the data file, which contains the raw data, so that
this information can later be used from a database. Thus I want to keep the relevant classes independent
of my current program.

Best regards
Christian

[quote]I do not want to move these methods to XManager,
since XManager is a general class, which can be used independently of the current application. [/quote]Then it looks like your solution is to create a new class inheriting from XManager and from which the 2 other classes would inherit.

Cheers,
Philippe

If you look at XPSData.h you will see the line “//class XDataManager: public XProcessManager”.
However, I was (and still am) reluctant to do this since XDataManager has nothing to do with XProcessManager.
Furthemore, I can create a library libData.so w/o the overhead of the processing code.
At the moment I believe for the first time, that multiple inheritance is the best solution.

Best regards
Christian

Hi Christian,

I was actually proposing something more like:

class XManagerWithAuthorInfo : public class XManager class XDataManager : public class XManagerWithAuthorInfo class XProcessManager : public class XManagerWithAuthorInfo A priori this is similar to the multiple inheritance solution.

The 3rd solution is to create an auxiliary class XAuthorInfo which will be embedded in your 2 classes. and the AuthorInfo method would be forwarding to that sub object.

Cheers,
Philippe.

PS. I am assuming since you say that XProcessManager and XDataManager have nothing to do with each other, that your goal is only to avoid code replication.

Dear Philippe

You are right, my initial goal is to avoid code replication, but in the long term I would like to create
a database system, which should be able to connect to my current code but also work independently.
For this reason XManagerWithAuthorInfo (which I call XHandler) should not derive from XManager.

Best regards
Christian

Ok So that leave you with choosing between multiple inheritance and containment (either will work with ROOT).

Cheers,
Philippe

Yes, and although multiple inheritance causes some problems, e.g. the need to avoid “dreaded diamond”, I think that I will use it.

Thank you
Christian