для класса не существует конструктора по умолчанию

#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[])
{
}

Ошибка: IntelliSense: для класса "Blowfish" не существует конструктора по умолчанию ???!


person Abanoub    schedule 12.02.2011    source источник
comment
Пожалуйста, не удаляйте весь вопрос. Оставьте его на месте.   -  person greyfade    schedule 13.02.2011
comment
Отсутствие конструктора по умолчанию не проблема, если вы его не используете. Всегда указывать аргумент при построении — это нормально, когда нет очевидного аргумента по умолчанию.   -  person Bo Persson    schedule 13.02.2011
comment
Вопрос уже задан давно, все еще для завершения, чтобы заставить компилятор генерировать конструктор по умолчанию, который можно использовать: <classname> { public: <classname>() = default; } со значением по умолчанию, заставляющим конструктор по умолчанию для класса. В этом случае: class Blowfish { Blowfish() = default; }   -  person Max Kuchenkiller    schedule 07.11.2019


Ответы (4)


Если вы определяете класс без какого-либо конструктора, компилятор синтезирует для вас конструктор (и это будет конструктор по умолчанию, то есть такой, который не требует никаких аргументов). Однако если вы делаете определение конструктора (даже если он принимает один или несколько аргументов), компилятор не синтезирует конструктор за вас — в этот момент вы взяли на себя ответственность за создание объектов этого класса, поэтому компилятор, так сказать, «отступает назад» и оставляет эту работу вам.

У вас есть два варианта. Вам нужно либо предоставить конструктор по умолчанию, либо указать правильный параметр при определении объекта. Например, вы можете изменить свой конструктор, чтобы он выглядел примерно так:

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 и т. д. — это режимы работы, а не сами алгоритмы шифрования. Называть их алгоритмами не будет беспокоить компилятор, но может необоснованно вызвать проблемы у других, читающих код.

person Jerry Coffin    schedule 12.02.2011
comment
Что делать, если я пытаюсь инициализировать массив объектов Blowfish? то есть: Blowfish blowfish_[] ... как мне использовать ctor для этого? - person neid; 30.09.2014
comment
@nagheid: объекты в таком массиве всегда создаются с помощью конструкторов по умолчанию. На сегодняшний день самым простым обходным решением является std::vector, хотя вы можете сделать это самостоятельно с помощью std::aligned_storage и нового размещения - person Mooing Duck; 05.12.2014

Потому что у тебя есть это:

Blowfish(BlowfishAlgorithm algorithm);

Это не конструктор по умолчанию. Конструктор по умолчанию не принимает никаких параметров. то есть

Blowfish();
person Dave    schedule 12.02.2011

Конструктор по умолчанию — это конструктор, который либо не имеет параметров, либо, если они есть, все параметры имеют значения по умолчанию.

person Mārtiņš Briedis    schedule 12.02.2011

Вы объявили конструктор Blowfish следующим образом:

Blowfish(BlowfishAlgorithm algorithm);

Таким образом, эта строка не может существовать (без дальнейшей инициализации):

Blowfish _blowfish;

так как вы не передали параметр. Он не понимает, как обрабатывать объявление объекта "BlowFish" без параметров - для этого вам нужно создать другой конструктор.

person RageD    schedule 12.02.2011