3

我从我的 c++ 编译器得到一个奇怪的响应。我搜索了互联网,但没有找到任何有用或有帮助的...

编译器响应:

float.hpp|第 29 行|警告:`class HexFloatingPoint' 具有虚函数但非虚析构函数

在构造函数 `HexFloatingPoint::HexFloatingPoint(int, int)' 中:

float.cpp|第 5 行|错误:没有用于调用“FloatingPoint::FloatingPoint()”的匹配函数

float.hpp|第 16 行|注:候选对象是:FloatingPoint::FloatingPoint(const FloatingPoint&)

float.cpp|第 3 行|注:FloatingPoint::FloatingPoint(int, int)

这些是代码文件:

主文件

#include <iostream>
#include "floating.hpp"

using namespace std;

int main(int argc, char* argv[])
{

    return 0;
}

浮动.hpp

#ifndef FLOATING
#define FLOATING

#include <string>
#include <vector>

using namespace std;

class FloatingPoint;
class HexFloatingPoint;
class HexDigit;
class HexDigitBool;
class HexDigitChar;

class FloatingPoint
{
private:
    int significant_length;
    int exponent_length;

public:
    FloatingPoint(int sign_length,int exp_length);
    virtual void set_significant(string number) = 0;
    virtual void set_exponent(string number);
    virtual void print();
};

class HexFloatingPoint : public FloatingPoint
{
private:
    vector<HexDigit*> significant_length;
    vector<HexDigit*> exponent_length;
public:
    HexFloatingPoint(int sign_length,int exp_length);
    void set_significant(string number);
    void set_exponent(string number);
    void print();
    ~HexFloatingPoint();
};

class HexDigit
{
public:
    virtual void print()=0;
    virtual void set_value(char c);
    virtual int get_value();
};

class HexDigitBool : public HexDigit
{
private:
    bool b[4];
public:
    void print();
    virtual void set_value(char c);
    virtual int get_value();
};

class HexDigitChar : public HexDigit
{
private:
    char c;
public:
    void print();
    virtual void set_value(char c);
    virtual int get_value();
};


#endif

浮动.cpp

#include "floating.hpp"

FloatingPoint::FloatingPoint(int sign_length,int exp_length) : significant_length(sign_length),exponent_length(exp_length){}

HexFloatingPoint::HexFloatingPoint(int sign_length,int exp_length) : significant_length(sign_length),exponent_length(exp_length){}
void HexFloatingPoint::set_significant(string number){}
void HexFloatingPoint::set_exponent(string number){}
void HexFloatingPoint::print(){}
HexFloatingPoint::~HexFloatingPoint(){}

我希望你能帮助我。我已经尝试添加 FloatingPoint(); 在 floating.hpp 和 floating.cpp 但它没有帮助。

更新 1

将构造函数更改为

HexFloatingPoint::HexFloatingPoint(int sign_length,int exp_length) : FloatingPoint(sign_length,exp_length){}

编译器说不...

floating.o||In function `_ZNSt12_Vector_baseIP8HexDigitSaIS1_EED2Ev':|
stl_vector.h:(.text+0x8)||undefined reference to `vtable for FloatingPoint'|
floating.o||In function `_ZN13FloatingPointC1Eii':|
floating.cpp|3|undefined reference to `vtable for FloatingPoint'|'

更新 2

改变

class FloatingPoint
{
private:
    int significant_length;
    int exponent_length;

public:
    FloatingPoint(int sign_length,int exp_length);
    virtual void set_significant(string number) = 0;
    virtual void set_exponent(string number);
    virtual void print();
};

class FloatingPoint
{
private:
    int significant_length;
    int exponent_length;

public:
    FloatingPoint(int sign_length,int exp_length);
    virtual void set_significant(string number) = 0;
    virtual void set_exponent(string number) = 0;
    virtual void print() = 0;
};

解决了更新 1 中出现的错误

改变

class HexFloatingPoint : public FloatingPoint
{
private:
    vector<HexDigit*> significant_length;
    vector<HexDigit*> exponent_length;
public:
    HexFloatingPoint(int sign_length,int exp_length);
    void set_significant(string number);
    void set_exponent(string number);
    void print();
    ~HexFloatingPoint();
};

class HexFloatingPoint : public FloatingPoint
{
private:
    vector<HexDigit*> significant_length;
    vector<HexDigit*> exponent_length;
public:
    HexFloatingPoint(int sign_length,int exp_length);
    void set_significant(string number);
    void set_exponent(string number);
    void print();
    virtual ~HexFloatingPoint();
};

已解决的警告

改变

HexFloatingPoint::HexFloatingPoint(int sign_length,int exp_length) : significant_length(sign_length),exponent_length(exp_length){}

HexFloatingPoint::HexFloatingPoint(int sign_length,int exp_length) : FloatingPoint(sign_length,exp_length),significant_length(sign_length),exponent_length(exp_length){}

修复了第一个问题

非常感谢各位!!

4

4 回答 4

1
In constructor `HexFloatingPoint::HexFloatingPoint(int, int)':

floating.cpp|line 5|error: no matching function for call to `FloatingPoint::FloatingPoint()'

floating.hpp|line 16|note: candidates are: FloatingPoint::FloatingPoint(const FloatingPoint&)

floating.cpp|line 3|note: FloatingPoint::FloatingPoint(int, int)

一旦你为你的类提供了任何构造函数,如果你的代码调用无参数构造函数,你还必须显式地提供一个不带任何参数的构造函数。

警告清楚地告诉您,您的代码在调用构造函数时调用了无参数构造函数:

HexFloatingPoint(int, int)

所以要么:

这是一个重要的警告。您的类HexFloatingPoint有一个virtual成员函数,这意味着它还应该提供一个virtual析构函数。
请注意,如果您没有在基类中提供虚拟析构函数并且您调用delete指向派生类对象的基类指针,那么它将导致未定义的行为。

于 2013-01-22T15:56:34.020 回答
1

HexFloatingPoint派生自FloatingPoint,但您不会在FloatingPoint' 的构造函数的初始化列表中调用任何 ' 的构造HexFloatingPoint函数。这意味着被调用的默认(无参数)构造函数FloatingPoint,但类没有定义它,所以你得到错误。

要么调用FloatingPointinHexFloatingPoint的初始化列表的构造函数,要么给出FloatingPoint默认构造函数。

于 2013-01-22T15:58:11.550 回答
0

首先,错误。您的构造函数HexFloatingPoint没有初始化基类FloatingPoint. 由于您定义了一个带有两个参数的构造函数,并且没有默认构造函数(不包含参数),因此派生类必须使用您定义的构造函数对其进行初始化:

HexFloatingPoint::HexFloatingPoint(int sign_length,int exp_length) :
    FloatingPoint(sign_length, exp_length),  // ADD THIS
    significant_length(sign_length),
    exponent_length(exp_length)
{}

或者,您可能希望能够保持基类成员未初始化,或将它们初始化为默认值,在这种情况下,您需要提供默认构造函数:

FloatingPoint() {} // or initialise the members if you want

但这可能不是您想要做的;您可能想要正确初始化它们。

其次,警告。通常,当您拥有多态基类时,您会希望通过指向基类的指针来删除派生对象。仅当基类声明了虚拟析构函数时才允许这样做;否则,这种删除会产生未定义的行为。我建议您遵循编译器的建议并添加一个:

virtual ~FloatingPoint() {}

最后,一旦您修复了编译器错误(假设没有比您发布的代码更多的代码),由于缺少 and 的定义,您将收到链接器FloatingPoint::set_exponent错误FloatingPoint::print。这是因为您已将它们声明为虚拟但不纯,并且尚未实现它们。他们可能想成为纯虚拟的,例如set_significant

virtual void set_exponent(string number) = 0;
                                         ^^^
于 2013-01-22T16:08:43.557 回答
0

float.hpp|第 29 行|警告:`class HexFloatingPoint' 具有虚函数但非虚析构函数

向 HexFloatingPoint 添加一个虚拟析构函数:

virtual ~HexFloatingPoint(); 

一旦类具有虚函数,就需要声明/定义虚析构函数,否则如果通过基类指针或客户端代码中的引用访问派生类,派生类的析构函数可能不会'不要被调用,行为是未定义的。通常,对象的派生部分不会被删除(通过基引用或指针访问),在这种情况下,您会留下内存泄漏。查看有效 C++,第 7 项。

float.hpp|第 29 行|警告:`class HexFloatingPoint' 具有虚函数但非虚析构函数

为类定义构造函数后,不会自动定义默认构造函数 HexFloatingPoint(),您需要将其显式添加到类声明/定义中。

于 2013-01-22T15:58:47.633 回答