Когда виртуальный не работает - PullRequest
3 голосов
/ 24 декабря 2008

У меня странная ошибка в моих классах C ++ в данный момент. У меня есть класс-оболочка ActiveX (как часть wxWidgets), к которому я добавил новую виртуальную функцию. У меня есть другой класс, который наследуется от класса ActiveX (wxIEHtmlWin), однако класс ActiveX всегда вызывает свою собственную функцию вместо функции в wxIEHtmlWin, которая переопределяет ее.

Я не могу понять, почему это происходит. Я сделал функцию чисто виртуальной, и теперь программа вылетает при вызове функции, но в противном случае компилируется нормально. Есть ли способ отключить виртуальные функции или я обнаружил ошибку в Visual Studio?

ActiveX класс

protected:
virtual FrameSite* getNewFrameSite()=0;

wxIEHtmlВ классе

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

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

Редактировать: я добавил еще одну тестовую функцию (возвращает целое число) и все еще облажался.

Ссылка на код вопроса: http://lodle.net/public/iebrowser.rar

Edit:

ОК, благодаря ответу ниже, я получил его на работу. Что я сделал, так это создал класс activex из двух частей (как предложено), однако в wxIEHtmlWin я назвал вторую часть в коде конструктора. Вот так:

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

Теперь я знаю, почему wxWidgets поддерживает построение двух частей.

Ответы [ 2 ]

9 голосов
/ 24 декабря 2008

Вы вызываете виртуальный метод из конструктора класса (через другой вызов). Это вызовет метод для текущего класса, так как подкласс еще не создан. Исправление заключается в использовании метода init () и вызове его после создания класса.

т.е. что-то вроде этого:

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

  // in the code that uses these classes:
  wxActivex *activex = new IEHtmlFrame();
  activex->init();
1 голос
/ 03 февраля 2009

Более "выкинутая" версия этого вопроса может быть найдена здесь . Но вкратце, базовый объект не является (пока) экземпляром производного типа, поэтому он не может вызывать любые перегруженные функции для производного объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...