0

I am just trying to get my code to compile. I've done this before and it looks exactly the same in its methods, but for some reason, when I'm trying to run it using different methods, it won't compile. The error is in the cpp file. Any help would be great! Thanks

Error is:

/tmp/ccexQEF7.o: In function `Animal::Animal(std::string)':
Animal.cpp:(.text+0x11): undefined reference to `vtable for Animal'
collect2: error: ld returned 1 exit status

This is my header file:

#include <iostream>
#ifndef ANIMAL_H
#define ANIMAL_H

class Animal
{
  
  public:
  
    Animal(std::string name);
    std::string get_name();
    virtual int get_weight();
    virtual int get_age();
    
  protected:
    
    std::string animalName;
    
};

class Cat: public Animal
{
  
  public:
  
    Cat(double weight, int age);
    
    std::string get_name();
    virtual int get_age();
    virtual int get_weight();
    
  protected:
  
    std::string catType;     
};

#endif

This is my cpp file:

#include <iostream>
#include "Animal.h"
using namespace std;

Animal::Animal(string name)
{
    animalName = name;
};
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • You need to also implement remaining functions: `std::string get_name();`, `virtual int get_weight();`, `virtual int get_age();` – pptaszni Aug 20 '20 at 12:18
  • Does this answer your question? [Undefined reference to vtable](https://stackoverflow.com/questions/3065154/undefined-reference-to-vtable) – pptaszni Aug 20 '20 at 12:19
  • Thank you, but usually even without implementing the functions (which can be done later), the code should still compile even if the output is nothing. – Vanessa Bluebell Aug 20 '20 at 12:23
  • Nope if they are virtual. – pptaszni Aug 20 '20 at 12:24
  • There are two steps to creating an executable file. First you **compile** each source file; that creates an object file for each source file. Then you **link** the object files and any necessary libraries. That creates the executable file. The error message in the question comes from the linker. You can see that because the error message mentions "/tmp/ccexQEF7.o". The ".o" is the extension for an object file. In short: the code compiled okay, but didn't link because the linker couldn't find the vtable. g++ puts the vtable in with one of the virtual functions. Without them the code won't link. – Pete Becker Aug 20 '20 at 14:24

2 Answers2

1

You have either to define in the base class the virtual member function get_weight and get_age explicitly or declare them as pure virtual functions as for example

class Animal
{
  
  public:
  
    Animal(std::string name);
    std::string get_name();
    virtual int get_weight() = 0;
    virtual int get_age() = 0;
    
  protected:
    
    std::string animalName;
    
}

In derived classes you should override them using the specifier override as for example

    int get_weight() override;
    int get_age() override;

and provide their definitions.

Pay attention to that it would be better to declare the member functions as constant functions as for example

class Animal
{
  
  public:
  
    Animal(std::string name);
    std::string get_name();
    virtual int get_weight() const = 0;
    virtual int get_age() const = 0;
    
  protected:
    
    std::string animalName;
    
}

because it seems they do not change objects for which they are called.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

You have two undefined virtual methods:

   virtual int get_weight();
   virtual int get_age();

These methods have to be defined so that a vtable (virtual table) can be compiled for a class. At the very least, you need to give them a dummy implementation:

   virtual int get_weight() { return 0; }
   virtual int get_age() { return 0; }
Jan Schultke
  • 17,446
  • 6
  • 47
  • 96