【问题标题】:C++ error undefined reference to `vtable for XXX'C ++错误未定义对'vtable for XXX'的引用
【发布时间】:2016-10-28 02:00:14
【问题描述】:

我已经开始编写一个模拟 shell 程序,但很快就遇到了问题。 编译我的项目时,我得到了一个未定义的对 `vtable for Cmd' 的引用

Shell.h

#ifndef SHELL_H
#define SHELL_H
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h> 
#include <cstring>


using namespace std;

class Shell
{
protected:
char* cmd;

public:
Shell(): cmd(NULL){};
Shell(char* userInput): cmd(userInput){};
virtual bool execute() = 0;
};

#endif

Cmd.h

#ifndef CMD_H
#define CMD_H
#include <unistd.h>
#include <iostream>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <cstring>
#include "Shell.h"

using namespace std;

class Cmd : public Shell
{
public:
Cmd(): Shell(NULL) {};
Cmd(char* userInput): Shell(userInput) {};
bool execute();
};

#endif

Cmd.cpp

#include "Cmd.h"



bool Cmd::execute()
{
char * list[1000];
bool status = true;
return status;
}

我对此进行了研究,发现它可能来自我的 makefile 或我的虚拟函数 我的虚函数被声明了

生成文件

  COMPILE = g++
  FLAGS = -Werror -Wall -ansi


all:
mkdir -p ./bin
    $(COMPILE) $(FLAGS) ./src/main.cpp -o ./bin/rshell
main:
    $(COMPILE) $(FLAGS) ./src/main.cpp

Cmd:
    $(COMPILE) $(FLAGS) ./src/Cmd.cpp

Exit:
    $(COMPILE) $(FLAGS) ./src/Exit.cpp

Connector:
    $(COMPILE) $(FLAGS) ./src/Connector.cpp

And:
    $(COMPILE) $(FLAGS) ./src/And.cpp

Or:
    $(COMPILE) $(FLAGS) ./src/Or.cpp

Semi:
    $(COMPILE) $(FLAGS) ./src/Semi.cpp

clean:
rm -rf ./bin

【问题讨论】:

  • 显示的 makefile 已完全损坏。它试图将每个单独的翻译单元编译为独立的可执行文件,而不是将所有翻译单元链接到单个可执行文件中。
  • 您需要将所有文件编译并链接到一个程序中。
  • 我该怎么做呢?在线搜索提供了多种实现 makefile 的方法
  • @opera97 make(尤其是 GNU make)是非常强大的工具。因此,它允许您以多种不同的方式实现相同的效果。大多数在 Internet 上找到的 Makefile 都是由某些工具生成的,因此它们通常包含针对每个源文件的显式规则,例如:main.o: main.cpp shell.h 后跟仅编译的命令main.cpp 等。但是您实际上可以使用隐式规则编写非常通用的 Makefile,然后您只需更新源文件或预期目标文件的列表,隐式规则将使 make 找出必须编译/链接的内容以及如何。
  • 无论如何,你应该花几天时间研究制作文档,学习一些基础知识。或者切换到其他构建系统(最终可能类似的复杂性,尽管开始可能更简单)或 IDE(通常更简单,只是功能不那么强大)。但这么多年过去了,我还是更喜欢 GNUmake。每当我看到新的构建系统(最近是“gradle”)时,我都会对自己说:“又一个程序员懒得学习制定规则,添加了另一个无用的构建系统”...... :/(然后谷歌为 Android Studio 选择了它我只是想知道,我是疯了,还是他们?还是在做噩梦?我想醒来......)

标签: c++ inheritance makefile


【解决方案1】:

错误意味着您缺少对类中第一个虚拟方法的引用。

问题是你冲洗了你的makefile。

解的一般形式如下:

CXX=g++ -Werror -Wall -ansi -c
LD=g++
OBJS=/src/main.o src/Cmd.o src/Exit.o src/Connector.o src/And.o src/Or.o src/Semi.o

all: .PHONY
        mkdir bin
        $(LD) -o bin/rshell $(OBJS)

%.o: %.cpp Shell.h Cmd.h
        $(CXX) $(FLAGS) -o $@ $<

这里发生了几件事。

  1. 使用OBJS 和一个规则来节省大量输入。
  2. 使用 -c 编译每个 .cpp 文件以避免尝试过早链接。
  3. 作为最后一步的链接不会编译任何内容。
  4. 使用 .PHONY 所以编译不会阻塞,如果有人创建了一个名为 all 的文件。

【讨论】:

  • 可能是来自makefile之外的代码,我朋友的布局和他的makefile运行良好
  • 您的 makefile 试图将 main.cpp 单独编译成一个程序。这不可能。
  • 你介意回答我的问题吗,没有人给我一个深入的答案
猜你喜欢
  • 2011-12-01
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多