繁体   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