【问题标题】:I'm trying to write a class where the child class will inherit the methods from the parent class, but my code won't compile我正在尝试编写一个类,其中子类将从父类继承方法,但我的代码无法编译
【发布时间】:2023-04-01 12:26:01
【问题描述】:

我只是想让我的代码编译。我以前做过这个,它的方法看起来完全一样,但是由于某种原因,当我尝试使用不同的方法运行它时,它不会编译。错误在 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

这是我的 cpp 文件:

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

Animal::Animal(string name)
{
    animalName = name;
};

【问题讨论】:

  • 你还需要实现剩余的功能:std::string get_name();,virtual int get_weight();,virtual int get_age();
  • 这能回答你的问题吗? Undefined reference to vtable
  • 谢谢,但通常即使没有实现功能(可以稍后完成),即使输出什么也没有,代码仍然应该编译。
  • 如果它们是虚拟的就不行。
  • 创建可执行文件有两个步骤。首先你编译每个源文件;为每个源文件创建一个目标文件。然后您链接 目标文件和任何必要的库。这将创建可执行文件。问题中的错误消息来自链接器。您可以看到,因为错误消息提到“/tmp/ccexQEF7.o”。 “.o”是目标文件的扩展名。简而言之:编译好的代码,但没有链接,因为链接器找不到 vtable。 g++ 将 vtable 与其中一个虚函数一起放入。没有它们,代码将无法链接。

标签: c++ class inheritance virtual-functions function-definition


【解决方案1】:

您必须在基类中明确定义虚成员函数get_weightget_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;
    
}

在派生类中,您应该使用说明符 override 覆盖它们,例如

    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;
    
}

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

【讨论】:

    【解决方案2】:

    你有两个未定义的虚方法:

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

    必须定义这些方法,以便可以为类编译 vtable(虚拟表)。至少,你需要给他们一个虚拟的实现:

       virtual int get_weight() { return 0; }
       virtual int get_age() { return 0; }
    

    【讨论】:

    • 非常感谢,在看到您的回复之前我就可以编译了!但我还是很感激!
    • 不要认为你应该这样做。因为没有动物的重量为 0。最好将它们声明为纯虚拟。这为错误而哭泣
    猜你喜欢
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    相关资源
    最近更新 更多