簡體   English   中英

使用 main.cpp、node.cpp/.h 和 slist.cpp/.h 構建單鏈表 (C++) [var SLNode 未命名類型:錯誤]

[英]Building Singly Linked List (C++), using main.cpp, node.cpp/.h, and slist.cpp/.h [var SLNode does not name a type: error]

我正在構建一個使用 main.cpp 並有兩個其他文件作為依賴項的單向鏈表。 一個是具有節點類的 SLNode.cpp/.h 文件,另一個是具有單鏈表類的 SList.cpp/.h 文件。 我遇到的問題是,當我嘗試編譯時,終端說:“在 SLNode.h:13:0 中包含的文件中:SList.h:31:5: 錯誤:'SLNode' 未命名類型 SLNode*頭;”

由於我在評論部分收到的反饋,此問題已得到解決。 現在的新問題是,當我嘗試編譯時,終端給了我這個錯誤:

SList.cpp:(.text+0x49): 未定義對`SLNode::~SLNode()'的引用

但我認為這只是我糟糕的編程以及我沒有正確編寫代碼的事實。

main.cpp(稱為 pc18.cpp):

/*
 * Programming Challenge 18 - UNIT TEST
 *
 * written by Carlos D. Escobedo
 * created on 27 oct
 *
 * References: 
 */

#include "SList.h"

#include <cassert>
#include <cstdlib>
#include <iostream>
using namespace std;

/* for unit testing -- do not alter */
template <typename X, typename A>
void btassert(A assertion);
void unittest ();

int main () {
    unittest();

    return 0;
}

/*
 * Unit testing functions. Do not alter.
 */
void unittest () {

    unsigned short utCount = 13;
    unsigned short utPassed = 0;

    cout << "\nSTARTING UNIT TEST\n\n";

    SList list;

    try {
        btassert<bool>(list.getSize() == 0);
        cout << "Passed TEST 1: default constructor (size) \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 1: default constructor (size) #\n";
    }

    try {
        btassert<bool>(list.toString() == "");
        cout << "Passed TEST 2: toString \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 2: toString #\n";
    }

    list.removeHead();
    try {
        btassert<bool>(list.getSize() == 0);
        cout << "Passed TEST 3: removeHead \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 3: removeHead #\n";
    }

    list.insertHead(1);
    try {
        btassert<bool>(list.getSize() == 1);
        cout << "Passed TEST 4: insertHead \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 4: insertHead #\n";
    }

    try {
        btassert<bool>(list.toString() == "1");
        cout << "Passed TEST 5: toString \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 5: toString #\n";
    }

    list.removeHead();
    try {
        btassert<bool>(list.getSize() == 0);
        cout << "Passed TEST 6: removeHead \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 6: removeHead #\n";
    }

    try {
        btassert<bool>(list.toString() == "");
        cout << "Passed TEST 7: toString \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 7: toString #\n";
    }

    list.insertHead(10);
    list.insertHead(20);
    try {
        btassert<bool>(list.toString() == "20,10" && list.getSize() == 2);
        cout << "Passed TEST 8: insertHead,insertHead,toString,getSize \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 8: insertHead,insertHead,toString,getSize #\n";
    }

    list.removeHead();
    try {
        btassert<bool>(list.toString() == "10" && list.getSize() == 1);
        cout << "Passed TEST 9: removeHead,toString,getSize \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 9: removeHead,toString,getSize #\n";
    }

    list.insertHead(5);
    try {
        btassert<bool>(list.toString() == "5,10" && list.getSize() == 2);
        cout << "Passed TEST 10: insertHead,toString,getSize \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 10: insertHead,toString,getSize #\n";
    }

    list.clear();
    try {
        btassert<bool>(list.toString() == "" && list.getSize() == 0);
        cout << "Passed TEST 11: clear,toString,getSize \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 11: clear,toString,getSize #\n";
    }

    for (unsigned int i=0; i<1000; i++)
        list.insertHead(i);
    try {
        btassert<bool>(list.getSize() == 1000);
        cout << "Passed TEST 12: insertHead high load \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 12: insertHead high load #\n";
    }

    for (unsigned int i=0; i<1000; i++)
        list.removeHead();
    try {
        btassert<bool>(list.getSize() == 0);
        cout << "Passed TEST 13: removeHead high load \n";
        ++utPassed;
    } catch (bool b) {
        cout << "# FAILED TEST 13: removeHead high load #\n";
    }

    cout << "\nUNIT TEST COMPLETE\n\n";

    cout << "PASSED " << utPassed << " OF " << utCount << " UNIT TEST";
    if (utCount > 1) {
        cout << "S";
    }
    cout << "\n\n";
}

template <typename X, typename A>
void btassert (A assertion) {
    if (!assertion)
        throw X();
}

SLNode.h:

/*
 * SLNode.cpp
 * 
 * written by Carlos D. Escobedo
 * created on 20 oct
 * 
 * References: 
 */

#ifndef SLNODE_H
#define SLNODE_H

class SLNode {
public:
    SLNode();

    SLNode(int contents);

    ~SLNode();

    void setContents(int newContent);

    int getContents() const;

    void setNextNode(SLNode* newNode);

    SLNode* getNextNode() const;

private:
    SLNode* nextNode;
    int contents;
};
#endif

SLNode.cpp:

/*
 * SLNode.cpp
 * 
 * written by Carlos D. Escobedo
 * created on 20 oct
 * 
 * References: 
 */
#include "SLNode.h"
#include <iostream>

SLNode::SLNode() {
    nextNode = NULL;
    contents = 0;
}

SLNode::SLNode(int value) {
    nextNode = NULL;
    contents = value;
}

SLNode::~SLNode() {
    nextNode = NULL;
}

void SLNode::setContents(int newContent) {
    contents = newContent;
}

int SLNode::getContents() const {
    return contents;
}

void SLNode::setNextNode(SLNode* newNode) {
    nextNode = newNode;
}

SLNode* SLNode::getNextNode() const {
    return nextNode;
}

SList.h:

//SList.h

#ifndef SLIST_H
#define SLIST_H

#include "SLNode.h"

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

class SLNode;
class SList {
public:
    SList();

    ~SList();

    void insertHead(int value);

    void removeHead();

    void clear();

    unsigned int getSize() const;

    string toString() const;

private:
    SLNode* head;
    unsigned int size;
};

#endif

SList.cpp:

/*
 * SList.cpp
 *
 * written by Carlos D. Escobedo
 * created on 26 Oct
 *
 * References:
 */

#include "SList.h"

SList::SList() {
    head = NULL;
    size = 0;
}

SList::~SList() {
    SList::clear();
    delete head;
}

void SList::insertHead(int value) {
    head = new SLNode(value);
}

void SList::removeHead() {
    if (head != NULL) {
        delete head;            
    }
}

void SList::clear() {
    delete head;
}

unsigned int SList::getSize() const {
    return size;
}

string SList::toString() const {
    stringstream ss;
    /*
    if (head == NULL) {
        return "";    
    } else {
        for (int i = 0; i < (size-1); i++) {
           ss << head[i] << ", "; 
        }
        ss << head[size-1];
    }
    */
    return "hello";
}

生成文件:

# Target for programming challenge-18
# Date completed: 10-26-2015
pc18: pc18.cpp SList.cpp SList.h SLNode.cpp SLNode.h
    g++ -o challenge-18 pc18.cpp SList.cpp SLNode.h

從 SLNode.h 文件中刪除 #include "SList.h" 語句。 它不需要,我認為這就是導致錯誤的原因。

你有循環包含。 slnode.h 包括 slist.h。 slist.h 包含 slnode.h,由於包含保護而被跳過。 因此,當稍后在 slist.h 中遇到 SNode 名稱時,該類尚未聲明,您會收到錯誤消息。

由於 slnode.h 標頭不使用 slist.h 中的任何內容,因此不要包含它。 另一種方法是使用class SList; 轉發聲明類。

您的結構相互引用,並且您輸入的條件編譯意味着 SList 或 SLNode 將在另一個之前定義。

更改包含順序或更改條件編譯不會解決它 - 只是移動問題。

而是嘗試像這樣對結構/類進行前向聲明

class SLNode;
class SList {
    ....

和相同的只是定義之前SLNode ,做一個向前聲明SList ..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM