views:

386

answers:

2

I have a weird error in my C++ classes at the moment. I have an ActiveX wrapper class (as part of wxWidgets) that i added a new virtual function to. I have another class that inherits from the ActiveX one (wxIEHtmlWin) however the ActiveX class always calls its own function instead of the one in wxIEHtmlWin which overrides it.

I can't work out why this is happening. I made the function pure virtual and now the program crashes when it does the function call but compiles fine otherwise. Is there any way to disable virtual functions or have I found a bug in Visual Studio?

ActiveX class

protected:
virtual FrameSite* getNewFrameSite()=0;

wxIEHtmlWin class

class wxIEHtmlWin : public wxActiveX
{
protected:
    FrameSite* getNewFrameSite();
}

FrameSite* wxIEHtmlWin::getNewFrameSite()
{
    return new gcFrameSite(this);
}

Edit: I've added another test function (returns an int) and still screws up.

Link to code in question: http://lodle.net/public/iebrowser.rar

Edit:

OK thanks to the answer below i got it to work. What i did was create the activex class in two parts (like suggested) however in wxIEHtmlWin i called the second part in the constructor code. Like so:

wxIEHtmlWin::wxIEHtmlWin(wxWindow * parent, wxWindowID id, const wxPoint& pos,const wxSize& size,long style, const wxString& name) : wxActiveX()
{
    wxActiveX::Create(parent, PROGID, id, pos, size, style, name);
    SetupBrowser();
}

Now i know why wxWidgets supports two part construction.

+6  A: 

You are calling the virtual method from within the class's constructor (via another call). This will call the method on the current class as the sub-class hasn't been constructed yet. The fix is to use an init() method and call it after constructing the class.

i.e something like this:

class wxActivex {
  wxActivex() {}
  virtual void init() {
    getNewFrame();
  }
};

  // in the code that uses these classes:
  wxActivex *activex = new IEHtmlFrame();
  activex->init();
rq
hmm that could be why. Ill give it a test.
Lodle
Thanks. I take virtual class for granted and never thought that you couldnt use them in the constructer before the object was even made.
Lodle
Yep, this is a classic C++ gotcha.
rq
I would have written no special code in the base class constructor and set an init function virtual pure to force the child class implementer to set it in the same way it's said in this answer.
Klaim
the thing is i only need this virtual function if you are changing the class that handles the invoke function of activex otherwise the normal constructor is fine.
Lodle
A: 

A more "boiled down" version of this question can be found here. But in short, the base object isnt (yet) an instance of the derived type, therefor cant call any overloaded functions on the derived object.

mizipzor