1

I have created a class hierachy of sensor classes and a sensor factory and when compiling get an error message from the linker.

undefined reference to `vtable for TSensorFactory

I have tried to find a solution based on the answers available on stack overflow and elsewhere and have been trying to solve this for at least a day now, but so far nothing seems to work. The code for the header file is:

#ifndef TSENSORFACTORY_H_932713048
#define TSENSORFACTORY_H_932713048

#define DALLAS_TEMPERATURE_PRECISION 10
#define DALLAS_UPDATE_INTERVAL 5 * 60 * 1000        // every 5 minutes get temperature from the dallas sensors
#define DALLAS_READ_DELAY 3000                      // wait 1 second befiore reading after the request
#define DALLAS_MIN_TEMP -30
#define DALLAS_MAX_TEMP 60

#include <BaseObject.h>
#include <LinkedList.h>
#include <DallasTSensor.h>
#include <FixedTSensor.h>
#include <ExternalTSensor.h>

class TSensorFactory : public BaseObject
{
private:
    LinkedList<TSensor *> mPtrSensors;

    DallasTemperature *mPtrDallas = nullptr;
    bool mDallasRequested = false;
    time_t mDallasLastRead = 0;
    unsigned long mDallasInterval = DALLAS_UPDATE_INTERVAL;
 
public:
    TSensorFactory();
    TSensorFactory(unsigned long, const char*);
    ~TSensorFactory();

    TSensor *getSensorByID(unsigned long pId);

    size_t getSize();
    long setJson(JsonObject pObj);
    long getJson(JsonObject pObj);
    TSensor *createFromJson(JsonObject pObj);

    // methods for externally updatable sensors
    bool updateFromExternal(char *pSourceName, unsigned long id, float pTemp, time_t pTimeStamp);

    // Dallas related methods
    DallasTSensor *getSensorByDallasAddress(DeviceAddress pAddress);
    DallasTSensor *getSensorByDallasIndex(int pIndex);
    int scanDallas();
    void handleDallas(time_t pMillis);
    void initDallas(DallasTemperature *pPtrDallas, time_t interval);
};

#endif

The code for the .cpp file is:

#include <TSensorFactory.h>

TSensorFactory::TSensorFactory() : BaseObject()
{
    mDallasLastRead = false;
}

TSensorFactory::TSensorFactory(unsigned long pId, const char* pName) : BaseObject(pId, pName)
{
    BaseObject();
}

TSensorFactory::~TSensorFactory() {
    for (int i = 0; i <mPtrSensors.size(); i++){
        TSensor *o =  mPtrSensors.get(i);
        delete o;
    }

    mPtrSensors.clear();
}

// removed the other method bodies for clarity's sake

This is for an EPS8266, and I am using PlatformIO on Visual Studio Code

I know that this question has been asked befor, but the answers I have seen did not seem to apply, or at least did not solve the problem, so I would really appreciate any help I can get.

Chris
  • 19
  • 3
  • have you checked the destructor of BaseObject ? – artm Jul 28 '20 at 12:18
  • 5
    A linker error about a vtable often means a missing definition for a virtual function. Also double check the object for the .cpp file is actually passed to the linker. – aschepler Jul 28 '20 at 12:19
  • 1
    The vtable is often emitted with the first non-inlined virtual function body. Assuming the base-class destructor is virtual, it should be at `TSensorFactory::~TSensorFactory` in the cpp file. BTW, what is going on in the second constructor? What is `BaseObject();` for? – Useless Jul 28 '20 at 12:36
  • Thanks everyone for looking into this. It turns out that the BaseObject contains two virtual functions that where indeed not defined in TSensorFactory. No idea how I ovefrlooked that, I spend a day looking for the problem. @Useless, the BaseObject class contains information that all classes have such as a name and ID. – Chris Jul 29 '20 at 15:44
  • You misunderstood my second point. The BaseObject base-class subobject is constructed in the initializer list. The `BaseObject();` statement in the constructor _body_ is almost certainly wrong. – Useless Jul 29 '20 at 16:14

0 Answers0