title: Virtual functions causing link errors
body: <p>I am struggling with an issue while I am using external .h files in my project.</p>
  
  <p>I am using Qt5 with MSVC2012. In my main file, I am including a header file from a KDE application. I put some INCLUDEPATH in the .pro file to link correctly.</p>
  
  <p>The piece of code I am in trouble with is the following:</p>
  
  <pre><code>main.cpp
  ...
  #include &lt;Doc.h&gt;
  
  int main(int argc, char *argv[])
  ...
  </code></pre>
  
  <p>The <strong>Doc.h</strong> belongs to the KDE application source code. Including that file includes many other files in several directories in the KDE application source code.</p>
  
  <p>Currently, the <strong>KUndo2Stack.h</strong> and the <strong>KUndo2Stack.cpp</strong> files are the files I am struggling with since three days now.</p>
  
  <p>When I run QMake and compile, I get a link 2001 errors due to unresolved externals with virtual functions in the <strong>KUndo2QStack</strong> class defined and implemented in those files. Here is an extract:</p>
  
  <pre><code>#ifndef QT_NO_UNDOSTACK
  
  class KUNDO2_EXPORT KUndo2QStack : public QObject
  {
      Q_OBJECT
  //    Q_DECLARE_PRIVATE(KUndo2QStack)
      Q_PROPERTY(bool active READ isActive WRITE setActive)
      Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)
  
  public:
      explicit KUndo2QStack(QObject *parent = 0);
      virtual ~KUndo2QStack();
      void clear();
  
      void push(KUndo2Command *cmd);
  
      bool canUndo() const;
      bool canRedo() const;
      QString undoText() const;
      QString redoText() const;
  
      int count() const;
      int index() const;
      QString actionText(int idx) const;
      QString text(int idx) const;
  
  #ifndef QT_NO_ACTION
      QAction *createUndoAction(QObject *parent) const;
      QAction *createRedoAction(QObject *parent) const;
  #endif // QT_NO_ACTION
  
      bool isActive() const;
      bool isClean() const;
      int cleanIndex() const;
  
      void beginMacro(const QString &amp;text);
      void endMacro();
  
      void setUndoLimit(int limit);
      int undoLimit() const;
  
      const KUndo2Command *command(int index) const;
  
  public Q_SLOTS:
      void setClean();
      virtual void setIndex(int idx);
      virtual void undo();
      virtual void redo();
      void setActive(bool active = true);
  
  Q_SIGNALS:
      void indexChanged(int idx);
      void cleanChanged(bool clean);
      void canUndoChanged(bool canUndo);
      void canRedoChanged(bool canRedo);
      void undoTextChanged(const QString &amp;undoActionText);
      void redoTextChanged(const QString &amp;redoActionText);
  
  private:
      // from QUndoStackPrivate
      QList&lt;KUndo2Command*&gt; m_command_list;
      QList&lt;KUndo2Command*&gt; m_macro_stack;
      int m_index;
      int m_clean_index;
      KUndo2Group *m_group;
      int m_undo_limit;
  
      // also from QUndoStackPrivate
      void setIndex(int idx, bool clean);
      bool checkUndoLimit();
  
      Q_DISABLE_COPY(KUndo2QStack)
      friend class KUndo2Group;
  };
  
  class KUNDO2_EXPORT KUndo2Stack : public KUndo2QStack
  {
  public:
      explicit KUndo2Stack(QObject *parent = 0);
  
      // functions from KUndoStack
      QAction* createRedoAction(KActionCollection* actionCollection, const QString&amp; actionName = QString());
      QAction* createUndoAction(KActionCollection* actionCollection, const QString&amp; actionName = QString());
  };
  
  #endif // QT_NO_UNDOSTACK
  </code></pre>
  
  <p>Note that the unresolved links occur only for virtual functions. Those functions are implemented as it follows:</p>
  
  <pre><code>KUndo2QStack::~KUndo2QStack()
  {
  #ifndef QT_NO_UNDOGROUP
      if (m_group != 0)
          m_group-&gt;removeStack(this);
  #endif
      clear();
  }
  
  void KUndo2QStack::undo()
  {
      if (m_index == 0)
          return;
  
      if (!m_macro_stack.isEmpty()) {
          qWarning("KUndo2QStack::undo(): cannot undo in the middle of a macro");
          return;
      }
  
      int idx = m_index - 1;
      m_command_list.at(idx)-&gt;undo();
      setIndex(idx, false);
  }
  
  void KUndo2QStack::redo()
  {
      if (m_index == m_command_list.size())
          return;
  
      if (!m_macro_stack.isEmpty()) {
          qWarning("KUndo2QStack::redo(): cannot redo in the middle of a macro");
          return;
      }
  
      m_command_list.at(m_index)-&gt;redo();
      setIndex(m_index + 1, false);
  }
  
  void KUndo2QStack::setIndex(int idx)
  {
      if (!m_macro_stack.isEmpty()) {
          qWarning("KUndo2QStack::setIndex(): cannot set index in the middle of a macro");
          return;
      }
  
      if (idx &lt; 0)
          idx = 0;
      else if (idx &gt; m_command_list.size())
          idx = m_command_list.size();
  
      int i = m_index;
      while (i &lt; idx)
          m_command_list.at(i++)-&gt;redo();
      while (i &gt; idx)
          m_command_list.at(--i)-&gt;undo();
  
      setIndex(idx, false);
  }
  </code></pre>
  
  <p>I have turned this question upside down looking for answers on the web and the only time I got something was when I deleted the word virtual off all the related functions. It cancelled the errors but <strong>I got an unresolved link2019 error with the destructor</strong> of the class <strong>KUndo2Stack</strong> (see the code above). The destructor I am talking about is the default one, you won't see any definition or implementation of it.</p>
  
  <p>I need some help to understand what is really going on and how to fix it.</p>
  
  <p>Thanks!</p>
  
  <p><strong>Update</strong></p>
  
  <p>The exact error messages are:</p>
  
  <pre><code>main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl KUndo2QStack::metaObject(void)const " (?metaObject@KUndo2QStack@@UEBAPEBUQMetaObject@@XZ)
  
  main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __cdecl KUndo2QStack::qt_metacast(char const *)" (?qt_metacast@KUndo2QStack@@UEAAPEAXPEBD@Z)
  
  main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __cdecl KUndo2QStack::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@KUndo2QStack@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
  
  main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl KUndo2QStack::setIndex(int)" (?setIndex@KUndo2QStack@@UEAAXH@Z)
  
  main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl KUndo2QStack::undo(void)" (?undo@KUndo2QStack@@UEAAXXZ)
  
  main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl KUndo2QStack::redo(void)" (?redo@KUndo2QStack@@UEAAXXZ)
  
  main.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __cdecl KUndo2Stack::~KUndo2Stack(void)" (__imp_??1KUndo2Stack@@UEAA@XZ) referenced in function "public: virtual void * __cdecl KUndo2Stack::`scalar deleting destructor'(unsigned int)" (??_GKUndo2Stack@@UEAAPEAXI@Z)
  
  debug\whitehall_0_2.exe:-1: error: LNK1120: 7 unresolved externals
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>After I added <strong>Q_OBJECT</strong> into the KUndo2Stack class, the link errors related to the qmetaobject of KUndo2QStack disappeared. The same errors appeared related to the <strong>KUndo2Stack</strong> class this time</p>
  
  <pre><code>main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl KUndo2Stack::metaObject(void)const " (?metaObject@KUndo2Stack@@UEBAPEBUQMetaObject@@XZ)
  
  main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __cdecl KUndo2Stack::qt_metacast(char const *)" (?qt_metacast@KUndo2Stack@@UEAAPEAXPEBD@Z)
  
  main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __cdecl KUndo2Stack::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@KUndo2Stack@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
  </code></pre>
  
  <p>The other errors stayed the same.</p>