没有匹配函数来调用“标准构造函数”

时间:2013-01-22 15:55:00

标签: c++ class constructor

我从c ++编译器得到一个奇怪的回应。我搜索了互联网,但没有提出任何有用或有用的信息......

编译器响应:

  

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

     

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

     

floating.cpp |第5行|错误:没有匹配函数来调用`FloatingPoint :: FloatingPoint()'

     

floating.hpp |第16行|注意:候选者是:FloatingPoint :: FloatingPoint(const FloatingPoint&)

     

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

这些是代码文件:

的main.cpp

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

using namespace std;

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

    return 0;
}

floating.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

floating.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 个答案:

答案 0 :(得分: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)

所以:

  • 您应该明确提供无参数构造函数或
  • 如果您不想提供默认的无参数,则应使用 member initializer list 并从基类调用所需版本的构造函数基类的构造函数。

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

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

答案 1 :(得分:1)

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

FloatingPoint的初始化列表中调用HexFloatingPoint的构造函数,或者为FloatingPoint提供默认构造函数。

答案 2 :(得分:0)

  

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

向HexFloatingPoint添加虚拟析构函数:

virtual ~HexFloatingPoint(); 

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

  

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

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

答案 3 :(得分: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() {}

最后,一旦你修复了编译器错误(假设没有比你发布的更多的代码),由于缺少FloatingPoint::set_exponentFloatingPoint::print的定义,你会得到链接器错误。这是因为你已经宣布它们是虚拟的而不是纯粹的,并且没有实现它们。他们可能希望像set_significant一样纯粹虚拟:

virtual void set_exponent(string number) = 0;
                                         ^^^
相关问题