user2000878
user2000878

Reputation: 31

no matching function to call to "standard constructor"

I get a weird response from my c++ compiler. I searched the internet but came up with nothing usefull or helpfull...

Compiler Response:

floating.hpp|line 29|warning: `class HexFloatingPoint' has virtual functions but non-virtual destructor

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)

These are the code files:

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(){}

I hope that you can help me. I already tried to add FloatingPoint(); in floating.hpp and floating.cpp but it didn't help.

UPDATE 1

Changed Constructor to

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

Compiler said no ...

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'|'

UPDATE 2

Changing

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();
};

to

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;
};

resolved the errors occured in update 1

changing

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();
};

to

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();
};

resolved warning

changing

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

to

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

fixed first problem

Thanks a lot guys!!

Upvotes: 3

Views: 4633

Answers (4)

Mike Seymour
Mike Seymour

Reputation: 254701

First, the error. Your constructor for HexFloatingPoint is not initialising the base class, FloatingPoint. Since you have defined a constructor taking two arguments, and no default constructor (containing no arguments), derived classes must initialise it using the constructor you've defined:

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

Alternatively, you might want to be able to leave the base-class members uninitialised, or initialise them to default values, in which case you'll need to provide a default constructor:

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

but this probably isn't what you want to do; you probably want to initialise them properly.

Secondly, the warning. Often when you have a polymorphic base class, you'll want to delete objects of the derived through a pointer to the base class. This is only allowed if the base class declares a virtual destructor; otherwise, such deletion gives undefined behaviour. I suggest you follow the compiler's advice and add one:

virtual ~FloatingPoint() {}

Finally, once you've fixed the compiler errors then (assuming there's no more code than what you posted) you'll get linker errors due to missing definitions of FloatingPoint::set_exponent and FloatingPoint::print. This is because you've declared them virtual but not pure, and haven't implemented them. They probably want to be pure virtual like set_significant:

virtual void set_exponent(string number) = 0;
                                         ^^^

Upvotes: 0

Alok Save
Alok Save

Reputation: 206616

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)

Once you provide any constructor for your class you also have to explicitly provide a constructor which does not take any parameters if your code invokes the no argument constructor.

The warning clearly tells you that your code invokes a no argument constructor when it calls the constructor for:

HexFloatingPoint(int, int)

So either:

  • You should provide a no argument constructor explicitly or
  • You should use member initializer list and invoke the desired version of constructor from base class if you don't want to provide a default no argument constructor for the base class.

    floating.hpp|line 29|warning: `class HexFloatingPoint' has virtual functions but non-virtual destructor

This is an important warning. Your class HexFloatingPoint has an virtual member function which implies that it should also provide an virtual destructor.
Note that if you do not provide a virtual destructor in your base class and you call delete on a base class pointer pointing to a derived class object then it will result in Undefined Behavior.

Upvotes: 1

tmaric
tmaric

Reputation: 5497

floating.hpp|line 29|warning: `class HexFloatingPoint' has virtual functions but non-virtual destructor

Add a virtual destructor to the HexFloatingPoint:

virtual ~HexFloatingPoint(); 

As soon as a class has virtual functions, you need to declare/define a virtual destructor, otherwise if you access the derived class through a base class pointer or a reference in your client code, it may happen that the destructor of the derived class doesn't get called, the behaviour is undefined. Usually, the derived part of the object is not deleted (access via base reference or pointer) in which case, you are left with a memory leak. Check out Effective C++, item 7.

floating.hpp|line 29|warning: `class HexFloatingPoint' has virtual functions but non-virtual destructor

As soon as you define a constructor for a class, the default constructor HexFloatingPoint() is not defined automatically, you need to explicitly add it to the class declaration/definition.

Upvotes: 0

HexFloatingPoint is derived from FloatingPoint, but you don't call any of FloatingPoint's constructors in the initialiser list in HexFloatingPoint's constructor. This means the default (no-parameter) constructor of FloatingPoint gets called, but the class doesn't define it, so you get the error.

Either call a constructor of FloatingPoint in HexFloatingPoint's initialiser list, or give FloatingPoint a default constructor.

Upvotes: 1

Related Questions