A missing vtable usually means the first non-inline virtual member function has no definition
Asked Answered
E

5

24

I am pretty sure this question is duplicate, but my code is different here, the following is my code. It fails with a "Undefined symbols" error, not sure whats missing.

class Parent {
   public :
     virtual int func () = 0;
     virtual ~Parent();

 };


 class Child : public Parent {
     public :

     int data;
     Child (int k) {
        data = k;
      }
    int func() {   // virtual function
       cout<<"Returning square of 10\n";
        return 10*10;
    }

    void Display () {
    cout<<data<<"\n";

 }

 ~ Child() {

    cout<<"Overridden Parents Destructor \n";

 }
};



int main() {
  Child a(10);
 a.Display();

 }

The following is the O/P when compiled.

Undefined symbols for architecture x86_64:
  "Parent::~Parent()", referenced from:
      Child::~Child() in inher-4b1311.o
  "typeinfo for Parent", referenced from:
      typeinfo for Child in inher-4b1311.o
  "vtable for Parent", referenced from:
      Parent::Parent() in inher-4b1311.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
Endermic answered 6/8, 2015 at 17:9 Comment(1)
Try Parent::~Parent() = default;Knelt
W
28

Parent::~Parent() is not defined.

You can put the definition directly into the class definition:

class Parent {
   public :
     virtual int func () = 0;
     virtual ~Parent() {};
 };

Or define it separately. Or, since C++11, write virtual ~Parent() = default;.

In any case, a destructor needs a definition.

Wieland answered 6/8, 2015 at 17:11 Comment(2)
Can the destructor be avoided here altogether?Weaver
@Olshansk: not if you want to construct it at some point. If it's constructible, it must be destructible. virtual doesn't change that.Unite
D
12

To help anyone else that comes this way looking for help with "NOTE: a missing vtable usually means the first non-inline virtual member function has no definition."

In my case the error was caused by a missing = 0; at the end of the virtual definition. Make sure all the appropriate virtual definitions have = 0; at the end.

virtual HRESULT function(int testInput) = 0;

Hopefully this saves someone some time.

Disintegration answered 19/12, 2020 at 1:24 Comment(2)
"Make sure all the virtual definitions have = 0; at the end" I am sorry but = 0 is basically saying this virtual function is pure virtual, which will in turn turn the who class into abstract class, which sometimes is not the case we want. There can be classes with non-pure virtual functions. This answer is absolutely wrongExpansive
@Xavier. Thanks for your feedback, my answer clearly says "In my case the error was caused by...." It was intended to help anyone else that was facing the same problem as I had. It wasn't intended to redefine the spec, just clear up and help with the ambiguity of the error message. That does not make the answer absolutely wrong especially as you say "sometimes it's not the case" which means other times it's absolutely will be the case and therefor correct for those situations.Disintegration
C
4

It should be worth adding that having "no definition" also applies to empty functions.

I have many different subclasses that implement a pure virtual function in each. While I was going through these files to implement the function, I declared the function in the .h file and defined the function in the .cpp file. My plan was just to leave each function body blank for now and implement it later as I have many implementations to write.

However, this will not work. Depending on the compiler you're using, functions that have no body are removed in an attempt to optimize code:

void foo() // removed 
{
}

Because foo is removed, it is as if you never defined it and only declared it, hence "...virtual member function has no definition."

Carcinomatosis answered 18/8, 2021 at 11:47 Comment(0)
G
0

In my case a constructor was missing from child class so I added a constructor and the error resolved.

Gillie answered 25/7, 2023 at 18:54 Comment(0)
K
-1

There are a couple of things that are missing:

  1. You cannot overload destructors: Unlike other member functions, the destructor has no parameters and cannot be overloaded with different sets of parameters or return types.
  2. While defining func you need to add override.
  3. Since you are initializing the virtual function func it should be declared const.
  4. Set the destructor of the parent class to default. With the above changes the following code should work:
#include <iostream>

 class Parent { 
    public :
     virtual int func () const = 0;
     virtual ~Parent() = default;
    };

 class Child : public Parent {
     public :
     int data;
     Child (int k) {
        data = k;
      }
    int func() const override {   // virtual function
       cout<<"Returning square of 10\n";
        return 10*10;
    }

    void Display () {
    cout<<data<<"\n";
 }
};

int main() {
  Child a(10);
  a.Display();
 }
Keavy answered 6/7, 2023 at 5:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.