(объявлено неявно) не может быть ссылка - это удаленная функция - PullRequest
0 голосов
/ 26 апреля 2020

С помощью следующего кода я столкнулся с проблемой.

AB C .h

namespace abcd
{
    class ABC
    {
    public:
        ABC() = delete;
        ABC(const std::string& filename);
        virtual ~ABC();
        ABC(const ABC&) = delete;
        ABC(ABC&&) = default;
    };
}

XYZ.h

using namespace abcd;

class XYZ
{
public:
    void func();
private:
    ABC obj;
    ABC maskfilename(std::string filename);
};

XYZ. cpp

XYZ::func()
{
    obj = maskfilename("abcd.txt"); //Error
}

abcd::ABC XYZ::maskfilename(string filename)
{
    abcd::ABC ret;
    // blah blah...
    return ret;
}

Ошибка:

«abcd :: AB C :: operator = (const abcd :: AB C &)» (объявлена ​​неявно) не может быть указана - это удаленная функция

Я так понимаю, это класс только для конструктора перемещения (ABC).

Как правильно использовать это? Я хочу сохранить возвращаемое значение из maskfilename() в классе XYZ, чтобы его можно было использовать в других функциях класса XYZ.

Как устранить эту ошибку?

1 Ответ

0 голосов
/ 26 апреля 2020

Ссылаясь на MSV C ошибка C2280 :

Компилятор обнаружил попытку ссылки на удаленную функцию. Эта ошибка может быть вызвана вызовом функции-члена, которая была явно помечена как = удалено в исходном коде. Эта ошибка также может быть вызвана вызовом неявной специальной функции-члена структуры или класса, которая автоматически объявляется и помечается как удаленная компилятором. Для получения дополнительной информации о том, когда компилятор автоматически создает стандартные или удаленные специальные функции-члены, см. Специальные функции-члены.

В вашем случае, поскольку в вашем классе ABC имеется конструктор перемещения, компилятор неявно объявляет копию оператор присваивания как удаленный Вот почему вы получаете эту ошибку.

Поскольку вы хотите, чтобы ABC был классом только для перемещения, вы можете объявить оператор присваивания перемещения и использовать семантику перемещения в XYZ::func():

obj = std::move(maskfilename("abcd.txt"));

Вот возможная реализация вашего класса ABC:

class ABC
{
public:
    ABC() = delete;
    ABC(const std::string& filename) : mFilename(filename) {}
    virtual ~ABC() = default;
    ABC(const ABC&) = delete;
    ABC(ABC&&) = default;
    ABC& operator= (ABC&&) = default;
    std::string GetFilename() const { return mFilename; }

private:
    std::string mFilename;
};


В вашем классе XYZ вы не можете иметь переменную-член obj типа ABC, так как по умолчанию Конструктор удален. Если вам нужно использовать такой объект в других методах XYZ, вы можете использовать уникальный указатель на ABC. Поэтому я бы изменил это так:

XYZ.h: #include "AB C .h" #include

class XYZ
{
public:
    void func();

private:
    std::unique_ptr<ABC> obj;
    std::unique_ptr<ABC> maskfilename(std::string filename);
};

XYZ. cpp:

void XYZ::func()
{
    obj = std::move(maskfilename("abcd.txt"));
}

std::unique_ptr<ABC> XYZ::maskfilename(std::string filename)
{
    std::unique_ptr<ABC> ret = std::make_unique<ABC>(filename);
    // blah blah...
    return ret;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...