Derived classes problem: 'undefined reference to vtable' linker error with derived classes

Hi,

I'm beginning to work on a plugin framework for an application, which will work by dynamically loading shared/dynamic libraries that contain classes (unknown to the application) that derive from base classes (known to the application).

I'm using MinGW with GCC and GNU-Make. The compiler output is below, including the rather strange linker error.

g++ -DBUILDING_DLL -c -o plugin.o classes.cpp
g++ -shared -o plugin.dll plugin.o
plugin.o:classes.cpp:(.text$_ZN9baseClassC2Ev[baseClass::baseClass()]+0x8): undefined reference to `vtable for baseClass'
collect2: ld returned 1 exit status
mingw32-make: *** [plugin.dll] Error 1


The problem appears to be in baseClass' constructor, which I haven't defined. I get the same error, but twice, if I define baseClass' constructor as 'baseClass() {}', as I did with derivedClass (see code).

The code isn't too long, I'll post it below. Help is appreciated. I think I'm doing something wrong with constructors, but I'm not sure what.


classes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// classes.h

#ifndef CLASSES_H
#define CLASSES_H

#ifdef BUILDING_DLL
#define DLL_INTERFACE __declspec(dllexport)
#else
#define DLL_INTERFACE __declspec(dllimport)
#endif


class DLL_INTERFACE baseClass
{
public:
	virtual void testFunc();
};


class DLL_INTERFACE derivedClass : public baseClass {

public:
	derivedClass() {};
	~derivedClass() {};
	void testFunc();
	
private:
	void privateFunc();
};


#endif 



classes.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// classes.cpp

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

void derivedClass::testFunc()
{
	this->privateFunc();
	return;
}

void derivedClass::privateFunc()
{
	std::cout << "derivedClass::privateFunc()\n";
	return;
}



Makefile:
1
2
3
4
5
6
7
8
9
CPP = g++

all: plugin.dll

plugin.dll: plugin.o
	$(CPP) -shared -o $@ $?
	
plugin.o: classes.cpp classes.h
	$(CPP) -DBUILDING_DLL -c -o $@ classes.cpp
I think the problem is that you did not define testFunc in the base class. Also you shall define destructor as virtual.
Try this,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// classes.h

#ifndef CLASSES_H
#define CLASSES_H

#ifdef BUILDING_DLL
#define DLL_INTERFACE __declspec(dllexport)
#else
#define DLL_INTERFACE __declspec(dllimport)
#endif


class DLL_INTERFACE baseClass
{
public:
        virtual ~baseClass() { };
	virtual void testFunc() = 0;
};


class DLL_INTERFACE derivedClass : public baseClass {

public:
	derivedClass() {};
	~derivedClass() {};
	void testFunc() override;
	
private:
	void privateFunc();
};
#endif  
@vlad
Thanks. Defining testFunc in the base class did it:

1
2
3
4
5
6
class DLL_INTERFACE baseClass
{
public:
	virtual void testFunc() {};
	virtual ~baseClass() {};
};


As you can see, I also took your advice and made the destructor virtual. Omitting it didn't make a difference to compilation, but if you think it's a good idea, then thanks for the advice!

Also, this makes a lot more sense to me after reading this, which I just found after some searching: http://gcc.gnu.org/faq.html#vtables

Thanks again.
If you do not declare the base class destructor as virtual, then derived classes that need to free resources in their destructors will never get called from a base class pointer.
@clanmjc

Okay, that makes sense. Thanks.
Topic archived. No new replies allowed.