收到未定义的引用错误 c++ 继承/多态性

Receiving undefined reference error c++ inheritance/polymorphism

本文关键字:c++ 继承 多态性 错误 引用 未定义      更新时间:2023-10-16

我正在学习如何用c ++编程,并且正在尝试多态性。当我将这些cpp文件编译为目标文件时,我没有收到任何错误。当我尝试制作可执行文件时,出现以下错误:

/tmp/ccsiYtzo.o: In function `expression::expression()':
constant.cpp:(.text._ZN10expressionC2Ev[_ZN10expressionC5Ev]+0x30): undefined reference to `vtable for expression'
/tmp/ccsiYtzo.o:(.rodata+0x24): undefined reference to `typeinfo for expression'
collect2: error: ld returned 1 exit status

我正在使用以下命令进行编译:

g++ constant.cpp main.cpp -o expression

我对这条错误消息的理解是必须定义构造函数表达式,但我相信我已经定义了它。此外,我试图排除声明/定义 expression(),因为默认构造函数应该有效;但是,它会导致相同的错误。如能提供一些指导,将不胜感激。

表达式.h

class expression{
public:
    expression(){}
    int virtual eval();
    char virtual * infix();
    char virtual * postfix();
};
class constant : public expression{
public:
    constant(int);
    int eval();
    char * infix();
    char * postfix();
private:
    int constantInt;
};

常数.cpp

#include "expression.h"
#include <stdio.h>
#include <stdlib.h>
constant::constant(int i){
        constantInt = i;
}
int constant::eval(){
    return constantInt;
}
char * constant::infix(){
    char *retval = (char *) malloc(sizeof(char));
    sprintf(retval, "%d", constantInt);
    return retval;
}
char * constant::postfix(){
    return infix();
}

主.cpp

#include <iostream>
#include "expression.h"
using namespace std;
int main(){
    expression *test = new constant(5);
    cout << test -> eval();
    return 0;
}

首先,您应该在 .h 文件中插入包含保护。

您的

问题是您使用虚拟关键字声明您的class expression,但没有进行摘要(以 = 0 结尾)。这意味着编译希望看到它的定义。

要解决问题,或向类添加定义,请执行以下操作:

class expression{
public:
    expression(){}
    virtual ~expression() {}
    int virtual eval() {}
    char virtual * infix() {}
    char virtual * postfix() {}
};

或者让它抽象起来:

class expression{
public:
    expression(){}
    virtual ~expression() {};
    int virtual eval() = 0;
    char virtual * infix() = 0;
    char virtual * postfix() = 0;
};

通过在基类"expression"中使用关键字"virtual",可以将这些函数设置为由派生类重写。但是,仅凭这一点并不意味着它将始终被覆盖。链接器仍将强制基类具有标记为虚拟的符号(函数)的实现,以便在创建该类型的对象的情况下。

但是,在您的情况下,您似乎打算创建一个抽象的基类,即不应该有具体实例的基类。在这种情况下,你用尾随的 ' = 0 装饰你的抽象函数;' .这将它们标记为"纯虚拟"。这样,它们不仅不需要基类中的实现,而且如果您尝试定义一个,编译器也会出错。