1. ホーム
  2. c++

[解決済み] クラスにデフォルトコンストラクタが存在しない。

2022-01-21 22:32:06

質問

#include "Includes.h"


enum BlowfishAlgorithm
    {
        ECB,
        CBC,
        CFB64,
        OFB64,
    };

class Blowfish
{
public:
    struct bf_key_st
    {
        unsigned long P[18];
        unsigned long S[1024];
    };
    Blowfish(BlowfishAlgorithm algorithm);
    void Dispose();
    void SetKey(unsigned char data[]);
    unsigned char Encrypt(unsigned char buffer[]);
    unsigned char Decrypt(unsigned char buffer[]);
    char EncryptIV();
    char DecryptIV();
private:
    BlowfishAlgorithm _algorithm;
    unsigned char _encryptIv[200];
    unsigned char _decryptIv[200];
    int _encryptNum;
    int _decryptNum;
};

class GameCryptography
{
public:
    Blowfish _blowfish;
    GameCryptography(unsigned char key[]);
    void Decrypt(unsigned char packet[]);
    void Encrypt(unsigned char packet[]);
    Blowfish Blowfish;
    void SetKey(unsigned char k[]);
    void SetIvs(unsigned char i1[],unsigned char i2[]);
};




GameCryptography::GameCryptography(unsigned char key[])
{
}

Error:IntelliSense: no default constructor exists for class "Blowfish" ?!!!

解決方法は?

コンストラクタのないクラスを定義すると、コンパイラがコンストラクタを合成してくれます(そのコンストラクタはデフォルトコンストラクタ、つまり引数を必要としないコンストラクタになります)。しかし、もし する コンストラクタを定義すると、(たとえそれが 1 つ以上の引数を取るとしても)コンパイラは ない その時点で、あなたはそのクラスのオブジェクトを構築する責任を負ったことになり、コンパイラはいわば一歩下がって、その仕事をあなたに任せることになるのです。

選択肢は2つです。デフォルトのコンストラクタを用意するか、オブジェクトを定義するときに正しいパラメータを指定する必要があります。たとえば、コンストラクタを次のようなものに変更することができます。

Blowfish(BlowfishAlgorithm algorithm = CBC);

...そのため、ctorはアルゴリズムを(明示的に)指定せずに呼び出すことができます(その場合、アルゴリズムとしてCBCを使用します)。

もう一つの方法は、Blowfishオブジェクトを定義する際に、アルゴリズムを明示的に指定することです。

class GameCryptography { 
    Blowfish blowfish_;
public:
    GameCryptography() : blowfish_(ECB) {}
    // ...
};

C++ 11 (またはそれ以降) では、もうひとつのオプションが利用できます。引数を取るコンストラクタを定義し、定義しなかった場合のコンストラクタを生成するようにコンパイラに指示することができます。

class GameCryptography { 
public:

    // define our ctor that takes an argument
    GameCryptography(BlofishAlgorithm); 

    // Tell the compiler to do what it would have if we didn't define a ctor:
    GameCryptography() = default;
};

最後に、ECB、CBC、CFBなどは動作モードであって、暗号化アルゴリズムそのものではないことを述べておきます。これらをアルゴリズムと呼んでもコンパイラは困りませんが 他の人がコードを読むときに問題を起こす可能性が高いです。