【问题标题】:(declared implicitly) cannot be referenced -- it is a deleted function(隐式声明)不能被引用——它是一个被删除的函数
【发布时间】:2020-08-09 15:41:57
【问题描述】:

使用以下代码,我遇到了一个问题。

ABC.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::ABC::operator=(const abcd::ABC &)"(隐式声明)不能被引用——它是一个被删除的函数

我知道它只是移动构造函数类 (ABC)。

使用它的正确方法是什么?我想在XYZ 类中保留maskfilename() 的返回值,以便在XYZ 类的其他函数中使用。

我该如何解决这个错误?

【问题讨论】:

    标签: c++ c++11 constructor


    【解决方案1】:

    这是ABC类的声明:

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

    参考MSVC错误C2280

    编译器检测到尝试引用已删除的函数。这 错误可能是由调用已被调用的成员函数引起的 在源代码中明确标记为 = 已删除。这个错误也可以 由调用结构的隐式特殊成员函数引起 或被自动声明并标记为已删除的类 编译器。有关何时编译器自动的更多信息 生成默认或删除的特殊成员函数,请参阅特殊 成员函数。

    在您的情况下,除了转换构造函数之外,您的类 ABC 只有一个移动构造函数。编译器已将复制赋值运算符和移动赋值运算符隐式声明为已删除。这就是您收到此错误的原因。此行正在尝试调用您已删除的复制赋值运算符:

    obj = maskfilename("abcd.txt"); //Error
    

    由于您希望您的类是仅移动类,只需声明一个移动赋值运算符,然后同一行将调用您的移动赋值运算符。那么maskfilename返回的右值会被移动到obj中。

    这是你的类ABC的重新设计实现:

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

    在您的类XYZ 中,您不能有ABC 类型的成员变量ABC,因为默认构造函数已被删除。如果你需要在XYZ 的其他方法中使用这样的对象,你可以有一个指向ABC 的唯一指针。所以我会这样改变:

    XYZ.h:

    #include "ABC.h"
    #include <memory>
    
    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;
    }
    

    【讨论】:

    • 感谢您的意见。我试过了,我仍然看到像 Error 无法引用 "abcd::ABC" 的默认构造函数这样的问题——它是一个已删除的函数和 Error 函数 "abcd::ABC::operator=(const abcd::ABC &amp;)" (隐式声明)不能被引用——它是一个被删除的函数
    • 谢谢!但是在class XYZ 中声明ABC obj 对象的目的。所以我需要一种机制来在class XYZ的其他方法中使用obj。如何在不多次调用maskfilename 方法的情况下实现该功能。
    • @CodeDevil 如果您需要延迟构建,请考虑Optional&lt;ABC&gt;,它在构建之前可能“没有价值”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 2022-11-12
    • 2018-06-09
    • 1970-01-01
    • 2013-09-24
    • 2013-01-16
    • 2022-12-18
    相关资源
    最近更新 更多