试图找到已删除的函数

Posted

技术标签:

【中文标题】试图找到已删除的函数【英文标题】:Trying to locate a deleted function 【发布时间】:2019-12-04 21:58:36 【问题描述】:

在 C++ 中搞乱类,遇到一个错误,指出我试图引用已删除的函数。这是错误

C2280(Test &Test::operator = (const Test& : 试图引用已删除的函数)。

这是我的代码:

#include "pch.h"
#include <iostream>

using namespace std;

class Test 
public:
    int size;
    double* array;
public: 
    Test();
    Test& operator=(Test&& a);
    Test(int sizeArg) 
        size = sizeArg;
        array = new double[size];
    
    Test(Test&& arg) 
        size = arg.size;
        array = arg.array;
        arg.size = 0;
        arg.array = nullptr;
    
    ~Test()
    
        if (array != nullptr) 
            delete[]array;
        
    
;

int main()

    Test outTest;
    int x = 1;
    //Wont work since looking for a deleted function
    if (x = 1) 
        Test arg(200000000);
        outTest = arg;
    
    cout << outTest.array;

问题出在等号上的main()

【问题讨论】:

Test&amp; operator=(Test&amp;&amp; a); 你声明了赋值运算符,但从未实现它... 您的意思是在main() 中写if (x == 1) 吗? = 是赋值运算符,== 是比较运算符。 您没有复制构造函数,也没有赋值运算符。声明移动构造函数会使它们默认被删除。或者outTest = std::move(arg) if (array != nullptr) 毫无意义。只需delete[] array; gcc 和 clang 告诉你函数被删除的原因。 MSVC 不这样做吗? 【参考方案1】:

您应该会收到以下错误:

constexpr Test&amp; Test::operator=(const Test&amp;)’ is implicitly declared as deleted because ‘Test’ declares a move constructor or move assignment operator

这是一件好事,因为默认的复制赋值运算符会做得很糟糕。它会复制您的指针 - 您最终会得到两个都声称拥有数据的实例。两者都会稍后尝试 delete[] 它 - 结果是未定义的行为。

您可能应该实现The rule of three/five/zero 中提到的所有 5 个成员函数。

例子:

#include <algorithm>
#include <iostream>
#include <utility>

class Test 
public:
    int size;
    double* array;
public: 
    Test() : 
        size(0),
        array(nullptr)                    // make sure the default constructed array
                                          // is set to nullptr
    
    Test(int sizeArg) :
        size(sizeArg),
        array(new double[size])         // zero initialize the array
    
    // rule of five:
    Test(const Test& arg) :               // copy ctor
        size(arg.size),
        array(new double[size])
    
        std::copy(arg.array, arg.array+size, array);
    
    Test(Test&& arg) :                    // move ctor
        size(arg.size),
        array(std::exchange(arg.array, nullptr)) // get pointer from arg and give nullptr
                                                 // to arg
    
    Test& operator=(const Test& arg)     // copy assignment operator
        Test tmp(arg);                    // reuse copy constructor
        std::swap(*this, tmp);            // let "tmp" destroy our current array
        return *this;
     
    Test& operator=(Test&& arg)          // move assignment operator 
        size = arg.size;
        std::swap(array, arg.array);      // let the other object delete our current array
        return *this;
       
    ~Test() 
        delete[] array;                   // no "if" needed, it's ok to delete nullptr
    
;

int main()

    Test outTest;
    int x = 1;

    if(x==1)                            // use == when comparing for equality
        Test arg(2);
        outTest = arg;
    
    std::cout << outTest.array;

【讨论】:

以上是关于试图找到已删除的函数的主要内容,如果未能解决你的问题,请参考以下文章

从向量 C++ 中删除对象试图引用已删除的函数

调用递归函数时出现编译器错误 - “试图引用已删除的函数”

C++ 错误(C2280)试图访问已删除的函数 [关闭]

VS2019 C++ 错误 C2280 试图引用已删除的函数 inl

编译器错误 C2280,试图引用已删除的函数 operator=

unique_ptr & vector,试图访问已删除的函数,Visual Studio 2013