【问题标题】:learning c++: error: use of deleted function学习c++:错误:使用已删除函数
【发布时间】: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++ 程序的功能是完整的;仅取决于它包含的头文件。

标签: c++ class struct


【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-25
      • 2016-07-27
      • 2021-01-30
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 2014-04-16
      • 1970-01-01
      相关资源
      最近更新 更多