C++ vtable Error | 'undefined reference to vtable' Linker Error Solution

C++ vtable Error | 'undefined reference to vtable' Linker Error Solution

이 글의 핵심

C++ vtable error C++, vtable, "undefined, Introduction: "undefined reference to vtable for MyClass" explained in detail with practical examples.

Introduction: “undefined reference to vtable for MyClass"

"Declared virtual function but got linker error”

In C++, declaring virtual function without defining it causes vtable linker error.

Below is an implementation example using C++. Define a class to encapsulate data and functionality. Try running the code directly to check its operation.

// ❌ vtable error
class Base {
public:
    virtual void foo();  // Declaration only
    virtual ~Base();     // Declaration only
};

// Link error:
// undefined reference to `vtable for Base'

What This Guide Covers:

  • What is vtable?
  • vtable error causes
  • Solutions
  • Pure virtual functions

1. What is vtable?

vtable (Virtual Table)

vtable is virtual function table that determines which function to call at runtime.

Here is detailed implementation code using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

class Base {
public:
    virtual void foo() {
        std::cout << "Base::foo\n";
    }
    
    virtual void bar() {
        std::cout << "Base::bar\n";
    }
};

class Derived : public Base {
public:
    void foo() override {
        std::cout << "Derived::foo\n";
    }
};

// vtable structure (conceptual)
// Base vtable:
//   [0] -> Base::foo
//   [1] -> Base::bar
//
// Derived vtable:
//   [0] -> Derived::foo
//   [1] -> Base::bar

2. vtable Error Causes

Cause 1: Missing Virtual Function Definition

Below is an implementation example using C++. Define a class to encapsulate data and functionality. Try running the code directly to check its operation.

// ❌ No definition
// base.h
class Base {
public:
    virtual void foo();  // Declaration only
    virtual ~Base();     // Declaration only
};

// Link error: undefined reference to `vtable for Base'

Cause 2: Missing Destructor Definition

Below is an implementation example using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

// ❌ No destructor definition
class Base {
public:
    virtual ~Base();  // Declaration only
    
    virtual void foo() {
        std::cout << "foo\n";
    }
};

// Link error: undefined reference to `vtable for Base'

3. Solutions

Solution 1: Add Definition in .cpp

Here is detailed implementation code using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

// ✅ base.h
class Base {
public:
    virtual void foo();
    virtual ~Base();
};

// ✅ base.cpp
void Base::foo() {
    std::cout << "Base::foo\n";
}

Base::~Base() {
    std::cout << "~Base\n";
}

Solution 2: Inline Definition in Header

Below is an implementation example using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

// ✅ base.h
class Base {
public:
    virtual void foo() {
        std::cout << "Base::foo\n";
    }
    
    virtual ~Base() {
        std::cout << "~Base\n";
    }
};

Solution 3: Use = default

Below is an implementation example using C++. Define a class to encapsulate data and functionality. Try running the code directly to check its operation.

// ✅ base.h
class Base {
public:
    virtual void foo() {
        std::cout << "Base::foo\n";
    }
    
    virtual ~Base() = default;  // Default implementation
};

4. Pure Virtual Functions

Pure Virtual Function with = 0

Here is detailed implementation code using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.

// ✅ Pure virtual function
class Base {
public:
    virtual void foo() = 0;  // Pure virtual
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    void foo() override {
        std::cout << "Derived::foo\n";
    }
};

// Base b;  // Compile error: abstract class
Derived d;  // OK

Summary

Key Points

  1. vtable: Virtual function table for runtime dispatch
  2. Error cause: Virtual function declared but not defined
  3. Solution: Provide definition in .cpp or inline
  4. Pure virtual: Use = 0 for abstract interface
  5. Destructor: Always define virtual destructor

When to Use

Provide definition when:

  • Declaring virtual functions
  • Using virtual destructor
  • Implementing polymorphic base class

Don’t:

  • Declare virtual function without definition
  • Forget destructor definition
  • Mix up pure virtual (= 0) with regular virtual

Best Practices

  • ✅ Define all declared virtual functions
  • ✅ Use = default for simple destructors
  • ✅ Use = 0 for pure virtual functions
  • ❌ Don’t declare virtual without definition
  • ❌ Don’t forget virtual destructor definition

Master vtable for error-free C++ polymorphism! 🚀