0

I have this code in my fileType.h.

class FileType{
    private:
        School* m_school;
        string m_fileFormat;
        const string m_cfgFile;
        const string m_inputFile;

    public:
        FileType(string p_fileFormat, string p_cfgFile, string p_inputFile):
                 m_fileFormat(p_fileFormat), m_cfgFile(p_cfgFile), m_inputFile(p_inputFile) {};
        virtual bool parseInputFile();
        virtual bool writeOutputFile(const School& m_school);
        virtual bool checkFormat(); // TBD -- used to check the format of the input file
        virtual bool checkConstraints(); // TBD -- used to check things like only +ve 12 digit in the ID etc
        virtual ~FileType();
};

class XmlType:public FileType{

    public:
        XmlType(string p_fileFormat, string p_cfgFile, string p_inputFile):
            FileType(p_fileFormat, p_cfgFile, p_inputFile) {};
        virtual bool parseInputFile();
        virtual bool writeOutputFile(const School& m_school);
        virtual bool checkFormat(); // TBD -- used to check the format of the input file
        virtual bool checkConstraints(); // TBD -- used to check things like only +ve 11 digit in the ID etc

};


class CsvType:public FileType{

    public:
        CsvType(string p_fileFormat, string p_cfgFile, string p_inputFile):
            FileType(p_fileFormat, p_cfgFile, p_inputFile) {};
        virtual bool parseInputFile();
        virtual bool writeOutputFile(const School& m_school);
        virtual bool checkFormat(); // TBD -- used to check the format of the input file
        virtual bool checkConstraints(); // TBD -- used to check things like only +ve 11 digit in the ID etc

};

In my main I put in :

#include "fileType.h"

    FileType *inputFilePtr, *outputFilePtr;
    string stringOne, stringTwo, stringThree;
    inputFilePtr = new CsvType(stringOne, stringTwo, stringThree);

Now my linker tells me that I does not know about the symbols for constructors:

/cygdrive/c/Users/Owner/AppData/Local/Temp/cclieUAi.o:main.cpp:(.text$_ZN7CsvTypeC1ESsSsSs[CsvType::CsvType(std::basic_string, std::allocator >, std::basic_string, std::allocator >, std::basic_string, std::allocator >)]+0x1bf): undefined reference to vtable for CsvType' /cygdrive/c/Users/Owner/AppData/Local/Temp/cclieUAi.o:main.cpp:(.text$_ZN8FileTypeC2ESsSsSs[FileType::FileType(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)]+0x3a): undefined reference tovtable for FileType' collect2: ld returned 1 exit status

I tried making a dummy constructor with two ints and doing nothing. That worked, but once I put strings, this fails. Any idea what is wrong?

Nawaz
  • 353,942
  • 115
  • 666
  • 851
Moto
  • 1
  • possible duplicate of [Undefined reference to vtable](http://stackoverflow.com/questions/3065154/undefined-reference-to-vtable) – Mark B Oct 05 '11 at 17:59

2 Answers2

2

You've defined only the constructors, but you've not defined the virtual functions. Only declaring them is not enough. You've to define them as well, which means, the function should have function-body, containing some statements (though it can be blank as well).

//file.h
class A
{ 
   virtual void f(); //this is called declaration
};

//file.cpp
void A::f() //this is called definition
{
  //this is called function-body.
}
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • I did put empty functions in my fileType.cpp for the FileType class. FileType::~FileType() { delete m_school; } bool FileType::parseInputFile() { } bool writeOutputFile() { } bool checkFormat() { } bool checkConstraints() { } bool CsvType::parseInputFile() { } – Moto Oct 05 '11 at 17:59
  • 1
    @Moto Are you sure you're linking your program with fileType.cpp? – zdan Oct 05 '11 at 18:02
  • @Moto: You've not put them. Just check it out again! – Nawaz Oct 05 '11 at 18:02
  • I am so sorry, I forgot to add fileType.cpp to g++, obviously it did not know about it :( – Moto Oct 05 '11 at 18:19
0

you declared the virtual destructor but your subclasses don't have one!

where is virtual ~CsvType() { } and virtual ~XmlType() {}

if this is an abstract base class you might consider setting the functions of FileTypeto purely virtual by virtual bool parseInputFile() = 0; so that you can't construct an object of FileType.

Also after virtual bool parseInputFile() {} you don't require a ;

Alexander Oh
  • 24,223
  • 14
  • 73
  • 76