C++ C++;构造函数和析构函数

C++ C++;构造函数和析构函数,c++,g++,constructor,destructor,C++,G++,Constructor,Destructor,我在编译程序时遇到一些错误。它们与我的类指令的构造函数和析构函数有关 错误包括: /tmp/ccSWO7VW.o: In function `Instruction::Instruction(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)': ale.c:(.text+0x241): undefined reference to `vtable for I

我在编译程序时遇到一些错误。它们与我的类指令的构造函数和析构函数有关

错误包括:

/tmp/ccSWO7VW.o: In function `Instruction::Instruction(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)':
ale.c:(.text+0x241): undefined reference to `vtable for Instruction'
/tmp/ccSWO7VW.o: In function `Instruction::Instruction(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)':
ale.c:(.text+0x2ab): undefined reference to `vtable for Instruction'
/tmp/ccSWO7VW.o: In function `Instruction::~Instruction()':
ale.c:(.text+0x315): undefined reference to `vtable for Instruction'
/tmp/ccSWO7VW.o: In function `Instruction::~Instruction()':
ale.c:(.text+0x38d): undefined reference to `vtable for Instruction'
collect2: ld returned 1 exit status
/tmp/ccSWO7VW.o:在函数“指令::指令(std::基本字符串,int)”中:
ale.c:(.text+0x241):对“vtable for Instruction”的未定义引用
/tmp/ccSWO7VW.o:在函数“指令::指令(标准::基本字符串,int)”中:
ale.c:(.text+0x2ab):对“vtable for Instruction”的未定义引用
/tmp/ccSWO7VW.o:在函数“指令::~Instruction()”中:
ale.c:(.text+0x315):对“vtable for Instruction”的未定义引用
/tmp/ccSWO7VW.o:在函数“指令::~Instruction()”中:
ale.c:(.text+0x38d):对“vtable for Instruction”的未定义引用
collect2:ld返回了1个退出状态
这是我的密码:

//classses.h

#include <iostream>
#include <string>
using namespace std;

class Instruction{

  protected:
    string name;
    int value;

  public:
    Instruction(string _name, int _value);
    ~Instruction();
    void setName(string _name);
    void setValue(int _value);
    string getName();
    int getValue();
    virtual void execute();
};

//constructor
Instruction::Instruction(string _name, int _value){
    name = _name;
    value = _value;
}
//destructor
Instruction::~Instruction(){
    name = "";
    value = 0;
}
void Instruction::setName(string _name){
     name = _name;
}

void Instruction::setValue(int _value){
    value = _value;
}

string Instruction::getName(){
       return name;
}

int Instruction::getValue(){
    return value;
}
//classses.h
#包括
#包括
使用名称空间std;
课堂教学{
受保护的:
字符串名;
int值;
公众:
指令(字符串名称、int值);
~Instruction();
void setName(字符串_name);
无效设置值(int_值);
字符串getName();
int getValue();
虚空执行();
};
//建造师
指令::指令(字符串_名称,int _值){
名称=_名称;
值=_值;
}
//析构函数
指令::~指令(){
name=“”;
数值=0;
}
void指令::setName(字符串_名称){
名称=_名称;
}
无效指令::设置值(int\u值){
值=_值;
}
字符串指令::getName(){
返回名称;
}
int指令::getValue(){
返回值;
}
/////////////////////////////////////////////////////////////////////

//ale.cpp

    #include "headers.h"
    #include "functions.h"
    #include "classes.h"
    #include <list>


    using namespace std;

    int main(){

    return 0;
    }
//ale.cpp
#包括“headers.h”
#包括“functions.h”
#包括“classes.h”
#包括
使用名称空间std;
int main(){
返回0;
}

您没有定义虚拟函数和/或g++希望您将析构函数变为虚拟函数(因为您有假定继承的虚拟函数)

我猜问题是由于您在指令类中声明了一个虚拟方法“execute”,而从未在任何地方定义它。编译器必须为具有虚拟方法的类生成vtable对象,并且实际上只需要它的一个副本,因此他们通常只在定义第一个虚拟函数的编译单元(源文件)中执行此操作…

试试看

virtual void execute()=0;
这将使您的类抽象,这似乎是您想要的,因为没有定义execute


如果希望在多个.cpp文件中使用指令,则应将类方法的实现移动到一个classes.cpp文件中。

正如人们所说,问题在于execute()未实现。实现它,或者像Dan Hook所说的那样让它纯粹虚拟化

还有一句话:在许多情况下(可能大多数情况取决于您所编写的代码),您不需要实现析构函数。如果您想要一些特定的功能性(例如,将数据刷新到文件中),您只需要

只要没有指针(代码中就是这样),就不会有任何内存跟踪问题。只需移除析构函数:它安全且代码更少。
但是,如果只有一个成员是指针,那么一切都会变得混乱,您必须处理内存管理问题、内存泄漏和SEGFULTS;)

您用来编译和链接程序的命令行是什么?请注意,如果您想在头中的类之外定义函数/方法,请为它们指定
inline
说明符。旁注:您不需要该析构函数。“清零”数据是不必要的。但是使用虚拟析构函数可能是个好主意,因为这显然是一个基类。顺便说一下,在析构函数中指定空字符串或零是没有意义的。它的目的是销毁数据,而不是重新初始化数据。在你的情况下,空析构函数是足够的,析构函数不必是虚拟的(如,它不会创建编译器错误),它只是应该是为什么我把它放到我的回答的第二部分:)我认为问题是他的虚拟函数没有被定义,但是C++编译器是如此脆弱的物种……析构函数可以被保护而不是虚拟的,这也可以工作。对不起?如果析构函数不是虚拟的,那么在删除对象时,将调用由变量类型指定的析构函数,而不是对象的实际类型。受保护的析构函数不会使其成为虚拟的,充其量它会给出一个编译错误。-1如果该类有任何虚拟成员,则极有可能通过指向基的指针删除派生类实例。在这种情况下,一个人肯定也需要一个虚拟析构函数。-不过,它的实现可以是空的。通过在父析构函数的末尾自动调用其析构函数,并将其设置为空字符串(在此之前没有任何用处),可以销毁字符串成员。