对vtable的未定义引用(类)

时间:2019-01-22 08:51:29

标签: c++ qt

我收到此错误:

Linking CXX executable muse3.exe
driver/libmuse_driver.a(qttimer.obj):qttimer.cpp:(.rdata$.refptr._ZTVN8MusECore10InnerTimerE[.refptr._ZTVN8MusECore10InnerTimerE]+0x0): undefined reference to `vtable for MusECore::InnerTimer'
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [muse\CMakeFiles\muse.dir\build.make:212: muse/muse3.exe] Error 1
mingw32-make[1]: *** [CMakeFiles/Makefile2:600: muse/CMakeFiles/muse.dir/all] Error 2
mingw32-make: *** [Makefile:151: all] Error 2

我了解该消息有点不清楚,并且问题可能出在某种方法上。

这是我的.h文件:

#ifndef __QTTIMER_H__
#define __QTTIMER_H__


#include <fcntl.h>
#include <QThread>
#include <QBasicTimer>
#include <QTimerEvent>

#include "timerdev.h"

namespace MusECore {

//---------------------------------------------------------
//   QtTimer
//---------------------------------------------------------

class InnerTimer : public QObject {
  Q_OBJECT
  int writePipe;
  long int tickCount;
  QBasicTimer timer;
public:
   void setupTimer(int fd, int timeoutms);
   ~InnerTimer();
   long int getTick();
   bool isRunning() { return timer.isActive(); }

protected:
   void timerEvent(QTimerEvent *event);

};

class QtTimer : public Timer, public QThread {

    int writePipe;
    int readPipe;
    bool keepRunning;
    InnerTimer *innerTimer;
    int timeoutms;
    public:
       QtTimer();
       virtual ~QtTimer();

       virtual signed int initTimer(unsigned long init);
       virtual long unsigned int setTimerResolution(unsigned long resolution);
       virtual long unsigned int getTimerResolution();
       virtual long unsigned int setTimerFreq(unsigned long freq);
       virtual long unsigned int getTimerFreq();

       virtual bool startTimer();
       virtual bool stopTimer();
       virtual long unsigned int getTimerTicks(bool printTicks=false);

       void setFindBestTimer(bool ) { }
    private:
       virtual void run();
};

} // namespace MusECore

#endif //__QTTIMER_H__

这是.cpp文件:

#include <cstdio>
#include <unistd.h>
#include <fcntl.h>
#include "qttimer.h"

#ifndef TIMER_DEBUG
#define TIMER_DEBUG 1
#endif

#ifdef _WIN32
#define pipe(fds) _pipe(fds, 4096, _O_BINARY)
#endif

namespace MusECore {


  QtTimer::QtTimer()
     {
     if(TIMER_DEBUG)
       fprintf(stderr,"QtTimer::QtTimer(this=%p) called\n",this);
     innerTimer = NULL;
     timeoutms = 10;
     readPipe=-1;
     writePipe=-1;
     }

  QtTimer::~QtTimer()
    {
    if(TIMER_DEBUG)
       fprintf(stderr,"QtTimer::~QtTimer(this=%p) called\n",this);
    exit(); // thread exit
    }

  signed int QtTimer::initTimer(unsigned long)
  {
    if(TIMER_DEBUG)
      printf("QtTimer::initTimer(this=%p)\n",this);

    int filedes[2];         // 0 - reading   1 - writing
    if (pipe(filedes) == -1) {
          perror("QtTimer - creating pipe failed");
          exit(-1);
          }
#ifndef _WIN32
    int rv = fcntl(filedes[1], F_SETFL, O_NONBLOCK);
    if (rv == -1)
          perror("set pipe O_NONBLOCK");
#endif
    if (pipe(filedes) == -1) {
          perror("QtTimer - creating pipe1");
          exit(-1);
          }
    writePipe = filedes[1];
    readPipe = filedes[0];

    return filedes[0];
  }

  long unsigned int QtTimer::setTimerResolution(unsigned long)
    {
    return 0;
    }

  long unsigned int QtTimer::setTimerFreq(unsigned long freq)
    {
    if (freq > 1000)
      freq = 1000;
    if (freq < 100)
      freq = 100;
    timeoutms = 1000/freq;
    return 1000/timeoutms;
    }

  long unsigned int QtTimer::getTimerResolution()
    {
    return  20;
    }

  long unsigned int QtTimer::getTimerFreq()
    {
    return 1000/timeoutms;
    }

  bool QtTimer::startTimer()
    {
    QThread::start();
    return true;
    }

  bool QtTimer::stopTimer()
    {
    QThread::quit();
    return true;
    }

  unsigned long int  QtTimer::getTimerTicks(bool /*printTicks*/)
    {

    if(TIMER_DEBUG)
      printf("getTimerTicks()\n");
    unsigned long int nn;
    if (readPipe==-1) {
        fprintf(stderr,"QtTimer::getTimerTicks(): no pipe open to read!\n");
        return 0;
    }
    if (read(readPipe, &nn, sizeof(char)) != sizeof(char)) {
        fprintf(stderr,"QtTimer::getTimerTicks(): error reading pipe\n");
        return 0;
        }
    //return nn;

    return innerTimer != 0 ? innerTimer->getTick() : 0;

    }

  void QtTimer::run()
  {

    //bool keepRunning = true;
    innerTimer = new InnerTimer();
    innerTimer->setupTimer(writePipe, timeoutms); // make sure it is running in the right thread

    exec();
  }

  void InnerTimer::setupTimer(int fd, int timeoutms)
  {
    tickCount=0;
    writePipe = fd;
    timer.start(timeoutms, this);
    printf("InnerTimer::setupTimer() started\n");

  }

  InnerTimer::~InnerTimer()
  {
    timer.stop();
  }

  void InnerTimer::timerEvent(QTimerEvent *event)
  {
    //if (tickCount%1000)
      //printf("InnerTimer::timerEvent %ld ++++++++++++++++++++++\n",tickCount);

    if (event->timerId() == timer.timerId()) {
      tickCount++;
      write(writePipe,"t",1);
    }

  }

  long int InnerTimer::getTick()
  {
    return tickCount;
  }

} // namespace MusECore

我已经阅读了有关此错误的其他文章,并且它们大多指向一些未定义的虚拟方法。但是,对我来说,似乎所有东西都定义正确,而且我也定义了析构函数。

有人可以指出我出了什么问题吗?

0 个答案:

没有答案