How can I override the member of (->) operator of a base class

132 views Asked by At

Background: I have Qt generated UI classes with no common ancestor. I am subclassing a class (say, "Door") that uses one of these UI classes, and the derived class ("OakDoor") will use a different UI class, although much of the UI elements will have the same name.

Until now I have been hiding the base UI class (i.e the derivied class uses a UI class of different type but the same name) but now need to rely on inheritance to handle cases where the base class does work on the UI classes; hiding doesn't work in this case.

I have already asked about a way to do this using inheritance and got pointed in the direction of using composition. So I am trying to find an efficient way to do this without having to define an access function for every UI element. It's not really composition but I thought it was getting me close for little effort.

class form_container 
{
public:
  form_container(){};
  form_container(Ui_A_Form * form){_form = form;}
  ~form_container(){ delete _form; }  
  Ui_A_Form *_form;
  Ui_A_Form & operator->()
  {
    return *_form;
  }
};

the idea was then to have Door use this class and OakDoor a subclass of it:

class B_form_container : public form_container
{
public:
  B_form_container(Ui_B_Form * form){_form=form;}
  ~B_form_container(){delete _form;}  
  Ui_B_Form  *_form;
  Ui_B_Form & operator->()
  {
    return *_form;
  }
};

So I'm really just shifting the hiding. Anyway the problem seems to be with my overloading of the operator ->(). In my Door class, I have form_container *_myform; which is constructed thusly:

_myform = new form_container(new A_Form());

But it won't compile when I try to access anything in an A_Form, for instance the Qt SetupUI function:

_myform->setupUi(_a_widget);

I'm obviously doing something wrong. Would appreciate any help out there - many thanks! (I can see problems when the subclass tries to delete _form in the base class but I'll sort that out later)

Edit: OK this is compiling now (many thanks to @(R Sahu)), but I am not seeing the overloading that I expect. e.g:

class base_class()
{
   form_container *_myform;
};

class derived_class(): public base_class()
{
 //inherit _myform;
};

//(constructor for derived class)
derived_class()::derived_class()
{
  _myform = new B_form_container(new B_form());
  (*_myform)->setupUI(new QWidget());  // tries to setupUi on an A_form
}

This is calling form_container::operator->(), presumably because it isn't virtual. If I make it virtual in the base class form_container, the derived class B_form_container complains about the function only differing by return type. Is there a way around this? Can I do something like this for instance:

class base : public A_form
{
 virtual base * operator->()
 {
    // not sure how to return ->() operator of A_form
    return A_form::operator->(); // ???
 }
};

class derived : public base, public B_form
{
 virtual base *operator->()
 {
   return B_form::operator->(); // again??? 
 }
} ;

Another edit: I don't think what I am trying to do is possible anymore. If you can correct me, please do. In the meantime I'm off to write something to process moc output and create classes with access functions which I can override.

2

There are 2 answers

5
mike On BEST ANSWER

As I eventually realised above, this isn't possible. The operator ->() has to return the type upon which it is acting, and for that reason it can't be used as a virtual function.

2
R Sahu On
_myform = new form_container(new A_Form());
_myform->setupUi(_a_widget);

is not the right syntax to use to access the operator->() function. With that syntax, the compiler expects a member function setupUi() in the class form_container. The right syntax is:

_myform = new form_container(new A_Form());
(*_myform)->setupUi(_a_widget);
// This translates to:
// Invoke the operator->() function on (*_myform)
// Use the return value of the function and call `setupUi()` on the returned pointer.

or

_myform = form_container(new A_Form());
_myform->setupUi(_a_widget);

Also, the function needs to return a pointer, not a reference.

Ui_B_Form* operator->()
{
  return _form;
}