When virtual doesn't work

2020-03-25 05:11发布

问题:

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.

回答1:

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();


回答2:

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.