C++ – Virtual tables are undefined

c++design-patternslinkervtable

I wrote some code but I am unable to compile it:

#include <cstdio>
#include <vector>

using namespace std;

class Visitor;

class Land {
  public:
    virtual void accept(const Visitor *v);
};

class England : public Land {
  public:
    void accept(const Visitor *v);
};

class Russia : public Land {
  public:
    void accept(const Visitor *v);
};

class Visitor {
  public:
    void visit(const England *e) const;
    void visit(const Russia *r) const;
};

class Trip {
  private:
    vector<Land> *l;
  public:
    explicit Trip(vector<Land> *_l);
    void accept(Visitor *v);
};

/**/

void Visitor::visit(const England *e) const {
  printf("Hey, it's England!\n");
}

void Visitor::visit(const Russia *r) const {
  printf("Hey, it's Russia!\n");
}

void Russia::accept(const Visitor *v) {
  v->visit(this);
}

void England::accept(const Visitor *v) {
  v->visit(this);
}

Trip::Trip(vector<Land> *_l):l(_l) {}

void Trip::accept(Visitor *v) {
  for (unsigned i = 0; i < l->size(); i++) {
    l->at(i).accept(v);
  }
}

int main() {
  England england;
  Russia russia;
  vector<Land> trip_plan;
  trip_plan.push_back(england);
  trip_plan.push_back(russia);
  trip_plan.push_back(england);
  Trip my_trip(&trip_plan);
  Visitor me;
  my_trip.accept(&me);
  return 0;
}

This is what I got from g++:

c++ -ansi -Wall -Wextra -Wconversion -pedantic -Wno-unused-parameter  -o vp vp.cc
/tmp/ccNanCPR.o: In function `Land::Land()':
vp.cc:(.text._ZN4LandC2Ev[Land::Land()]+0xf): undefined reference to `vtable for Land'
/tmp/ccNanCPR.o: In function `Land::Land(Land const&)':
vp.cc:(.text._ZN4LandC1ERKS_[Land::Land(Land const&)]+0x13): undefined reference to `vtable for Land'
/tmp/ccNanCPR.o: In function `Land::~Land()':
vp.cc:(.text._ZN4LandD1Ev[Land::~Land()]+0xf): undefined reference to `vtable for Land'
/tmp/ccNanCPR.o:(.rodata._ZTI6Russia[typeinfo for Russia]+0x10): undefined reference to `typeinfo for Land'
/tmp/ccNanCPR.o:(.rodata._ZTI7England[typeinfo for England]+0x10): undefined reference to `typeinfo for Land'
collect2: ld returned 1 exit status

This question is based on Circular dependencies of declarations

Best Solution

I already answered it there. The rules for vtable instantiation are explained in your compiler documentation.

Here, it is waiting to see the definition (body) of Land::accept, which you declared to be a non-pure virtual, but never defined. Either define it, or make it pure virtual.