学习c++:错误:使用已删除函数

Posted

技术标签:

【中文标题】学习c++:错误:使用已删除函数【英文标题】:learning c++: error: use of deleted function 【发布时间】:2017-04-17 18:36:00 【问题描述】:

我正在做“像程序员一样思考”一书中的一些练习,到目前为止一切都很好。 我开始了类章节,但在这里我似乎被卡住了,因为我无法解决编译代码时遇到的错误。

这里是代码。这不是我的,我一直在写它试图理解它。

struct studentRecord 
    int studentId;
    int grade;
    string name;
    studentRecord(int a, int b, string c); 
;

class studentCollection 
  private:
    struct studentNode 
        studentRecord studentData;
        studentNode *next;
    ;
  public:
    studentCollection();
    void addRecord(studentRecord newStudent);
    studentRecord recordWithNumber(int idNum);
    void removeRecord(int idNum);
  private:
    //typedef studentNode *studentList;
    studentNode *_listHead;
;

studentRecord::studentRecord(int a, int b, string c) 
    studentId = a;
    grade = b;
    name = c;


studentCollection::studentCollection() 
    _listHead = NULL;



void studentCollection::addRecord(studentRecord newStudent) 
    studentNode *newNode = new studentNode;
    newNode->studentData = newStudent;
    newNode->next = _listHead;
    _listHead = newNode;


studentRecord studentCollection::recordWithNumber(int idNum) 
    studentNode *loopPtr = _listHead;
    while (loopPtr != NULL && loopPtr->studentData.studentId != idNum) 
        loopPtr = loopPtr->next;
    
    if (loopPtr == NULL) 
        studentRecord dummyRecord(-1, -1, "");
        return dummyRecord;
     else 
        return loopPtr->studentData;
    


int main()  
    studentCollection s;
    studentRecord stu3(84, 1152, "Sue");
    studentRecord stu2(75, 4875, "Ed");
    studentRecord stu1(98, 2938, "Todd");
    s.addRecord(stu3);
    s.addRecord(stu2);
    s.addRecord(stu1);

我得到的错误是:

studentclass1.cpp: In member function ‘void studentCollection::addRecord(studentRecord)’:
studentclass1.cpp:45:32: error: use of deleted function ‘studentCollection::studentNode::studentNode()’
     studentNode *newNode = new studentNode;
                                ^~~~~~~~~~~
studentclass1.cpp:17:12: note: ‘studentCollection::studentNode::studentNode()’ is implicitly deleted because the default definition would be ill-formed:
     struct studentNode 
            ^~~~~~~~~~~
studentclass1.cpp:17:12: error: no matching function for call to ‘studentRecord::studentRecord()’

【问题讨论】:

如果这本书真的教你使用原始的拥有指针和内存泄漏,你应该把它扔掉并get a better book。 为什么您和其他许多在这里发帖的人发现发布带有预处理器指令的实际代码如此困难? 使用nullptr 而不是NULL @Gill studentNodestudentCollection 中声明 是的。 C++ 程序的功能是完整的;仅取决于它包含的头文件。 【参考方案1】:

当您定义struct 时,例如:

struct studentNode 
    studentRecord studentData;
    studentNode *next;
;

它有一个隐式定义的默认构造函数,相当于:

struct studentNode 
    studentNode() : studentData(), next() 
    studentRecord studentData;
    studentNode *next;
;

这是一个问题,因为studentRecord 的默认构造函数由于存在用户定义的构造函数而被编译器删除。

您可以向studentRecord 添加一个默认构造函数来解决这个问题。

struct studentRecord 
    int studentId;
    int grade;
    string name;
    studentRecord() = default; 
    studentRecord(int a, int b, string c); 
;

与其使用计算机生成的带有= default; 说明符的默认构造函数,不如使用有效数据初始化对象。

struct studentRecord 
    int studentId;
    int grade;
    string name;
    studentRecord() : studentRecord(0, 0, "")  // Delegate to the other constructor. 
    studentRecord(int a, int b, string c); 
;

【讨论】:

这样的默认构造函数很容易出错,因为它不会初始化成员 studentIdgrade 编译器生成的编译器实际上并没有默认初始化studentDatanext @GillBates,你很可能是对的。我无法理解对象的整个初始化过程。【参考方案2】:

studentRecord 不可默认构造,因为您提供了用户构造函数 (studentRecord(int a, int b, string c);)。因此studentNode 不能有编译器生成的默认构造函数。自己提供一个,或者给studentRecord一个默认构造函数。

【讨论】:

【参考方案3】:

结构studentRecord 有一个用户定义的构造函数

struct studentRecord 
    int studentId;
    int grade;
    string name;
    studentRecord(int a, int b, string c); 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;

在这种情况下,编译器不会为结构生成默认构造函数。

同时在函数addRecord里面

void studentCollection::addRecord(studentRecord newStudent) 
    studentNode *newNode = new studentNode;
                           ^^^^^^^^^^^^^^^^
    newNode->studentData = newStudent;
    newNode->next = _listHead;
    _listHead = newNode;

尝试使用结构studentRecord 的默认构造函数。由于无法使用,编译器将结构studentNode的默认构造函数定义为已删除。

您可以通过显式提供数据成员 studentRecord studentData 的初始化程序并使用聚合初始化来避免错误

函数可以这样写

void studentCollection::addRecord(studentRecord newStudent) 
    studentNode *newNode = new studentNode  newStudent, _listHead ;
    _listHead = newNode;

【讨论】:

以上是关于学习c++:错误:使用已删除函数的主要内容,如果未能解决你的问题,请参考以下文章

在 qt C++ 信号和槽中使用已删除函数错误

c++ 错误:使用已删除的函数 boost::asio::io_context::io_context

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

Visual Studio 2013 和 2015 中的 C++ 编译器错误 C2280“试图引用已删除的函数”

C++错误C2280 - 试图引用一个已删除的函数 - 在基元类型上。

C++ 在 GCC 上使用已删除的函数,但在 MSVC 上没有