34

File A.h

#ifndef A_H_
#define A_H_

class A {
public:
    virtual ~A();
    virtual void doWork();
};

#endif

File Child.h

#ifndef CHILD_H_
#define CHILD_H_

#include "A.h"

class Child: public A {
private:
    int x,y;
public:
    Child();
    ~Child();
    void doWork();
};
#endif

And Child.cpp

#include "Child.h"

Child::Child(){
    x = 5;
}

Child::~Child(){...}

void Child::doWork(){...};

The compiler says that there is a undefined reference to vtable for A. I have tried lots of different things and yet none have worked.

My objective is for class A to be an Interface, and to seperate implementation code from headers.

2
  • 4
    You must define every non-pure virtual function that you declare. You don't need to define a non-virtual function that you declare but don't use. Commented Feb 23, 2012 at 23:51
  • 2
    This question is similar to: Undefined reference to vtable. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Jun 19 at 10:07

3 Answers 3

78

Why the error & how to resolve it?

You need to provide definitions for all virtual functions in class A. Only pure virtual functions are allowed to have no definitions.

i.e: In class A both the methods:

virtual ~A();
virtual void doWork();

should be defined(should have a body)

e.g.:

A.cpp

void A::doWork()
{
}
A::~A()
{
}

Caveat:
If you want your class A to act as an interface(a.k.a Abstract class in C++) then you should make the method pure virtual.

virtual void doWork() = 0;

Good Read:

What does it mean that the "virtual table" is an unresolved external?
When building C++, the linker says my constructors, destructors or virtual tables are undefined.

Sign up to request clarification or add additional context in comments.

3 Comments

Having virtual ~A(); virtual void doWork() = 0; still gives vtable error =/. But without the destructor it works fine. However without it, if i do something like: A *a = new Child(); delete a; obviously it will not call Child::~Child(). Is there a workaround?
The solution is to place A::~A(){} in Child.cpp
With C++11, you can use "default" keyword to let the compiler do the job. ex: virtual doSomething() = default;
6

My objective is for A to be an Interface, and to seperate implementation code from headers.

In that case, make the member function as pure virtual in class A.

class A {
  // ...
  virtual void doWork() = 0;
};

5 Comments

That removes the error if I also remove the destructor. In that case if i do: A a = new Child(); delete a; what destructor would it call?
Destruction is always in reverse order of construction. In this case, class A destructor must be virtual which enforces Child destructor called first followed by A destructor. If the A class destructor is not virtual then the behavior is undefined.
It will call the child's destructor as you have made the parent class destructor virtual. After that, the parent class's destructor.
Having both the destructor and the pure virtual doWork(), in A, leads to a vtable error. How can i define a virtual destructor so that: A *a = new Child(); delete a; leads to a call to Child::~Child()?
The solution is to place A::~A(){} in Child.cpp
3

Make sure to delete any "*.gch" files if none of the other responses help you.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.