Undefined reference to vtable for screen logger

Nov 16, 2018 at 5:50am
So im working on an assignment for school and i keep on getting an error that says: undefined reference to vtable.
I already tried defining all my virtual function. I have tried multiple things such as virtual destructor, defining all virtual functions and what not. If someone could please explain whats wrong with my code, i would greatly appreciate it. I am using multiple files as well. the screenLogger.h file is the one that is giving me issues. When i fix them, i will get issues in screenLogger.cpp..... when i fix them, then the singleton class gives me errors.....

************CS1337Logger.cpp file******************************
# include <iostream>
# include "CS1337Logger.h"

// Set LoggerEnabled value
void CS1337Logger::setLogging(bool x)
{
loggingEnabled = x ;
}

//log message
void CS1337Logger::logMessage(const char * x)
{
if ( loggingEnabled == true )
{
displayMessage(x);
}
}

// get LoggerEnabled value
bool CS1337Logger::getLogging() const
{
return loggingEnabled ;
}


// Constructor
CS1337Logger::CS1337Logger()
{
loggingEnabled = false ;
}

//Virtual Destructor
CS1337Logger::~CS1337Logger()
{
}

**********cs1337logger.h file**************************

#ifndef CS1337LOGGER_H_
#define CS1337LOGGER_H_

class CS1337Logger
{
private:

// holds logging enabled value
bool loggingEnabled ;

public:

// setter method(mutator)
void setLogging(bool) ;
void logMessage(const char * );

// getter method(accessor)
bool getLogging() const ;

//virtual function. Makes class pure virtual (abstract)
virtual void displayMessage(const char* ) = 0;

//constructor
CS1337Logger();

//destructor
virtual ~CS1337Logger();
};



#endif /* CS1337LOGGER_H_ */

**********FileLogger.cpp file**************************************
# include <iostream>
# include "FileLogger.h"

using namespace std;

//Define displayMessage function
void FileLogger::displayMessage(const char* x)
{
logName << x << endl ;
}

//constructor
FileLogger::FileLogger()
{
logName.open("Log.txt"); // open the file to write to.
if( !logName ) // code segment for file being read. if file doesn't open do:
{
cout << "\nLog file was NOT opened successfully. Terminating program. " ; //Error Message
logName.close(); // close input file
exit(EXIT_FAILURE); // Error Code : 1 means file was not opened successfully
}
}

//destructor
FileLogger::~FileLogger()
{
logName.close();
}

*************FileLogger.h file*********************************
#include <fstream>
#include "CS1337Logger.h"
using namespace std ;

#ifndef FILELOGGER_H_
#define FILELOGGER_H_

class FileLogger : public CS1337Logger
{

private:

ofstream logName ;

public:

//virtual function. redefining
void displayMessage(const char* );

//constructor
FileLogger();

//destructor
virtual ~FileLogger();
};



#endif /* FILELOGGER_H_ */

************ScreenLogger.h file**************************************

# include <iostream>
# include "ScreenLogger.h"


//Define displayMessage function
void displayMessage(const char* x)
{
std::cout << x << std::endl ;
}

//constructor
/*ScreenLogger::ScreenLogger(){


}

//destructor
ScreenLogger::~ScreenLogger(){

}*/

*********ScreenLogger.cpp file******************************
#include "CS1337Logger.h"
using namespace std ;

#ifndef SCREENLOGGER_H_
#define SCREENLOGGER_H_

class ScreenLogger : public CS1337Logger
{

public:

//virtual function. redefining
void displayMessage(const char* );

//constructor
// ScreenLogger();

//destructor
// virtual ~ScreenLogger();
};



#endif /* SCREENLOGGER_H_ */


******LogSingleton.h file**********************************

#include "CS1337Logger.h"
#include "ScreenLogger.h"
#include "FileLogger.h"
#ifndef LOGSINGLETON_H_
#define LOGSINGLETON_H_

class LogSingleton
{


static CS1337Logger* GetLogger;
LogSingleton();

public:

static CS1337Logger* getLogger();

~LogSingleton();
};

*******LogSingleton.cpp file*********************************

#include "LogSingleton.h"
#include <iostream>
using namespace std ;

//allocate memory for static variable
CS1337Logger *LogSingleton::GetLogger = 0 ;

//define getLogger method. Check that only one instance of the logger exists
CS1337Logger* LogSingleton::getLogger()
{
if(GetLogger == NULL ) // if instance doesnt exist, create one.
{
//LogSingleton::GetLogger = new FileLogger (); //to log in files uncomment
GetLogger = new ScreenLogger (); // to log in console uncomment
}

return GetLogger ; // return my instance
}

***main.cpp file********************************************************
//This is just a test driver. just wanna make sure things work well.

#include "LogSingleton.h"
#include <iostream>

using namespace std ;

void test( bool s)
{
CS1337Logger * object = LogSingleton::getLogger();
cout << "Logging Status: " << object->getLogging() << endl ;
object->setLogging(s) ;
cout << "Logging Status: " << object->getLogging() << endl ;
object->logMessage("If you are reading this, then setLogging is Enabled.") ;
}

int main()
{
test(true);
test(false);
test(true);

}
Nov 16, 2018 at 6:35am
Try uncommenting ScreenLogger's ctor and dtor. I know you've probably already tried that. But do it, run it that way, and post that version along with the entire, exact (copy/pasted) error message.

Post the code in code tags:

[code]
your code goes here
maintains indentation
adds syntax highlighting
lowers cholesterol
[/code]

And if you expect people to be able to run it, a link to a zip file would be nice (just the .cpp and .h files).
Nov 16, 2018 at 6:38am
Please use the code tags, your code is hard to read otherwise.

Strangely enough, the problem is in ScreenLogger.cpp. This:
1
2
3
4
5
//Define displayMessage function
void displayMessage(const char* x)
{
    std::cout << x << std::endl ;
}


should be:
1
2
3
4
5
//Define displayMessage function
void ScreenLogger::displayMessage(const char* x)
{
    std::cout << x << std::endl ;
}
Nov 16, 2018 at 7:47am
Well-spotted, kbw!
Nov 16, 2018 at 7:54am
Thank you kbw!
Topic archived. No new replies allowed.