Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 学习c++;:错误:使用已删除的函数_C++_Class_Struct - Fatal编程技术网

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

C++ 学习c++;:错误:使用已删除的函数,c++,class,struct,C++,Class,Struct,我正在做《像程序员一样思考》一书中的一些练习,到目前为止一切都很好。 我开始了“类”一章,在这里我似乎被卡住了,因为我无法理解编译代码时遇到的错误 这是代码。这不是我的,我一直在写这本书,试图理解它 struct studentRecord { int studentId; int grade; string name; studentRecord(int a, int b, string c); }; class studentCollection {

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

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

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()’

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

定义
结构时,例如:

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); 
};

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

struct studentRecord {
    int studentId;
    int grade;
    string name;
    studentRecord(int a, int b, string c); 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
};
在这种情况下,编译器不会为结构生成默认构造函数

同时在函数内部添加记录

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;
}

如果这本书真的在教你如何使用原始的指针和泄漏的内存,你应该扔掉它。为什么你和其他在这里发帖的人都觉得很难发布实际的代码,完成预处理器指令?使用
nullptr
而不是
NULL
@Gill
studentNode
studentCollection
Yes中声明。一个C++程序的功能是如何完成的;取决于它包含的头文件。像这样的默认构造函数很容易出错,因为它不会初始化成员
studentId
grade
。编译器生成的编译器实际上不会默认初始化
studentData
next
。@GillBates,你很可能是对的。我还不能完整地了解对象的初始化过程。