2017-04-17 29 views
0

我正在做一些練習,從書中「像程序員一樣思考」,到目前爲止一切都很棒。 我開始了課程章節,在這裏我似乎被卡住了,因爲我無法將我的頭圍繞編譯代碼的錯誤。學習C++:錯誤:使用已刪除的函數

這是代碼。這不是我的,我一直在寫這本書,試圖理解它。

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

如果這本書是真正教你避免錯誤使用原始的擁有指針和內存泄漏,你應該把它扔掉,[得到一本更好的書](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 – nwp

+1

爲什麼你和其他許多人在這裏發帖,發現發佈實際代碼非常困難,並且完成了預處理器指令? –

+0

使用'nullptr'而不是'NULL' –

回答

4

當你定義一個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); 
}; 
+0

像這樣的默認構造函數會容易出錯,因爲它不會初始化成員'studentId'和'grade'。 – zett42

+1

@ zett42,是。我更新了答案。 –

+0

雖然編譯器生成的編譯器實際上並不默認初始化'studentData'和'next'。 –

2

studentRecord沒有缺省構造的,因爲你提供了一個用戶的構造函數(studentRecord(int a, int b, string c);)。因此studentNode不能有編譯器生成的默認構造函數。爲自己提供一個或給studentRecord默認構造函數。

1

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