C++ I';我试图编写一个类,其中子类将继承父类的方法,但我的代码赢了';不编译

C++ I';我试图编写一个类,其中子类将继承父类的方法,但我的代码赢了';不编译,c++,class,inheritance,virtual-functions,function-definition,C++,Class,Inheritance,Virtual Functions,Function Definition,我只是想让我的代码编译。我以前做过,它的方法看起来完全一样,但由于某种原因,当我尝试使用不同的方法运行它时,它不会编译。错误在cpp文件中。任何帮助都会很好!谢谢 错误是: /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

我只是想让我的代码编译。我以前做过,它的方法看起来完全一样,但由于某种原因,当我尝试使用不同的方法运行它时,它不会编译。错误在cpp文件中。任何帮助都会很好!谢谢

错误是:

/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
这是我的头文件:

#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
#包括
#ifndef动物实验室
#给动物下定义
类动物
{
公众:
动物(std::字符串名称);
std::string get_name();
虚拟整数get_weight();
虚拟整数get_age();
受保护的:
std::字符串animalName;
};
猫类:公共动物
{
公众:
Cat(双倍重量,整数);
std::string get_name();
虚拟整数get_age();
虚拟整数get_weight();
受保护的:
std::字符串类型;
};
#恩迪夫
这是我的cpp文件:

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

Animal::Animal(string name)
{
    animalName = name;
};
#包括
#包括“Animal.h”
使用名称空间std;
动物::动物(字符串名称)
{
动物名称=名称;
};

您有两个未定义的虚拟方法:

virtual int get_weight();
虚拟整数get_age();
必须定义这些方法,以便为类编译vtable(虚拟表)。至少,您需要为它们提供一个虚拟实现:

virtualint get_weight(){return 0;}
虚拟int get_age(){return 0;}

您必须在基类中明确定义虚拟成员函数
get\u weight
get\u age
,或者将它们声明为纯虚拟函数,例如

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;
    
}
    int get_weight() override;
    int get_age() override;
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;
    
}
在派生类中,应该使用说明符
override
覆盖它们,例如

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;
    
}
    int get_weight() override;
    int get_age() override;
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;
    
}
并提供它们的定义

请注意,最好将成员函数声明为常量函数,例如

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;
    
}
    int get_weight() override;
    int get_age() override;
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;
    
}

因为它们似乎不会更改调用它们的对象。

您还需要实现其余的函数:
std::string get_name()
virtualint get_weight()
虚拟整数get_age()这是否回答了您的问题?谢谢,但是通常即使没有实现函数(以后可以实现),即使输出为空,代码也应该编译。如果是虚拟的,则不编译。创建可执行文件有两个步骤。首先编译每个源文件;为每个源文件创建一个对象文件。然后链接对象文件和任何必要的库。这将创建可执行文件。问题中的错误消息来自链接器。您可以看到这一点,因为错误消息提到“/tmp/ccexQEF7.o”。“.o”是对象文件的扩展名。简而言之:代码编译正常,但没有链接,因为链接器找不到vtable。g++将vtable与其中一个虚拟函数放在一起。如果没有它们,代码将无法链接。非常感谢,在看到您的回复之前,我已经能够编译了!但我还是很感激!我不认为你应该这样做。因为没有动物的体重是0。最好宣布它们是纯虚拟的。这需要错误