3

C++コンパイラから奇妙な応答が返ってきます。私はインターネットを検索しましたが、何も役に立ちませんでした...

コンパイラの応答:

float.hpp | line 29 |警告: `class HexFloatingPoint'には仮想関数がありますが、非仮想デストラクタです

コンストラクターでは`HexFloatingPoint:: HexFloatingPoint(int、int)':

float.cpp | line 5 | error: `FloatingPoint :: FloatingPoint()'を呼び出すための一致する関数がありません

float.hpp | line 16 |注:候補は次のとおりです:FloatingPoint :: FloatingPoint(const FloatingPoint&)

float.cpp | line 3 |注:FloatingPoint :: FloatingPoint(int、int)

これらはコードファイルです:

main.cpp

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

using namespace std;

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

    return 0;
}

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

float.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();を追加しようとしました。float.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)

したがって、次のいずれかです。

  • 引数なしのコンストラクターを明示的に指定するか、
  • 基本クラスにデフォルトの引数なしコンストラクターを提供したくない場合は、メンバー初期化子リストを使用して、基本クラスから目的のバージョンのコンストラクターを呼び出す必要があります。

    floating.hpp|29 行目|警告: `class HexFloatingPoint' には仮想関数がありますが、非仮想デストラクタがあります

これは重要な警告です。クラスHexFloatingPointには、デストラクタvirtualも提供する必要があることを意味するメンバー関数があります。基本クラスで仮想デストラクタを提供せず、派生クラス オブジェクトを指す基本クラス ポインタ を呼び出すと、未定義の動作が発生することに注意してください。virtual
delete

于 2013-01-22T15:56:34.020 に答える
1

HexFloatingPointは から派生していますが、 のコンストラクターの初期化子リストで のコンストラクターをFloatingPoint呼び出していません。これは、gets のデフォルト (パラメーターなし) コンストラクターが呼び出されることを意味しますが、クラスはそれを定義していないため、エラーが発生します。FloatingPointHexFloatingPointFloatingPoint

FloatingPointinHexFloatingPointの初期化子リストのコンストラクターを呼び出すかFloatingPoint、デフォルトのコンストラクターを指定します。

于 2013-01-22T15:58:11.550 に答える
0

floating.hpp|29 行目|警告: `class HexFloatingPoint' には仮想関数がありますが、非仮想デストラクタがあります

仮想デストラクタを HexFloatingPoint に追加します。

virtual ~HexFloatingPoint(); 

クラスに仮想関数があるとすぐに、仮想デストラクタを宣言/定義する必要があります。そうしないと、基本クラス ポインタまたはクライアント コード内の参照を介して派生クラスにアクセスすると、派生クラスのデストラクタが呼び出されない場合、動作は未定義です。通常、オブジェクトの派生部分は削除されません (ベース参照またはポインターを介したアクセス)。この場合、メモリ リークが発生します。有効な C++ の項目 7 を確認してください。

floating.hpp|29 行目|警告: `class HexFloatingPoint' には仮想関数がありますが、非仮想デストラクタがあります

クラスのコンストラクターを定義するとすぐに、デフォルトのコンストラクター HexFloatingPoint() は自動的に定義されないため、クラスの宣言/定義に明示的に追加する必要があります。

于 2013-01-22T15:58:47.633 に答える
0

まず、エラー。のコンストラクターHexFloatingPointは、基本クラスを初期化していませんFloatingPoint。2 つの引数を取るコンストラクターを定義し、既定のコンストラクター (引数を含まない) を定義していないため、派生クラスは、定義したコンストラクターを使用してコンストラクターを初期化する必要があります。

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_exponentおよびの定義が欠落しているためにリンカー エラーが発生しますFloatingPoint::print。これは、それらを仮想として宣言したが純粋ではなく、実装していないためです。彼らはおそらく次のような純粋な仮想になりたいと思っていますset_significant:

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