使用main.cpp、node.cpp/.h和slist.cpp/.h[var SLNode未命名类型:error]构建

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

本文关键字:cpp 类型 未命名 error 构建 SLNode slist main node 使用 var      更新时间:2023-10-16

我正在构建一个使用main.cpp并具有另外两个文件作为依赖项的单链接列表。一个是具有节点类的SLNode.cpp/.h文件,另一个是拥有单链表类的SList.cpp//h文件。我遇到的问题是,当我尝试编译时,终端会说:"在SLNode.h:13:SList.h:3:5:错误:‘SLNode’没有命名类型SLNode*head;"

由于我在评论部分收到了反馈,这个问题已经得到了解决。现在的新问题是,当我尝试编译时,终端会给我这个错误:

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 TESTnn";
    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 COMPLETEnn";
    cout << "PASSED " << utPassed << " OF " << utCount << " UNIT TEST";
    if (utCount > 1) {
        cout << "S";
    }
    cout << "nn";
}
template <typename X, typename A>
void btassert (A assertion) {
    if (!assertion)
        throw X();
}

SL节点.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";
}

Makefile:

# 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包括slist.h。slist.h包括slnode.h,由于包含保护而跳过该slnode.h。因此,当稍后在slist.h中遇到SNode名称时,该类还没有声明,您会得到错误。

由于slnode.h标头不使用slist.h中的任何内容,因此不要包含它。另一种选择是使用class SList;来转发声明类。

从SLNode.h文件中删除#include"SList.h"语句。这是不需要的,我认为这就是造成错误的原因。

您的结构正在相互引用,并且您已经放入的条件编译意味着SList或SLNode将在另一个之前定义。

更改include顺序或更改条件编译并不能解决问题,只是转移问题。

相反,尝试像下面的一样对结构/类进行前向声明

class SLNode;
class SList {
    ....

同样在定义SLNode之前,做SList的前向声明。。