2015-11-05 1 views
-1

Я создаю отдельный список, который использует main.cpp и имеет два других файла в качестве зависимостей. Один из них - файлы SLNode.cpp/.h, которые имеют класс узлов, а другой - файлы SList.cpp/.h, которые имеют односвязный класс списка. Проблема, с которой я столкнулась, заключалась в том, что когда я пытаюсь скомпилировать, терминал говорит: «В файле, включенном из SLNode.h: 13: 0: SList.h: 31: 5: ошибка:« SLNode »не называет тип SLNode * глава;"Создание единого связанного списка (C++) с использованием main.cpp, node.cpp/.h и slist.cpp/.h [var SLNode не называет тип: ошибка]

Эта проблема была устранена благодаря обратной связи, полученной мной в разделе комментариев. Новый вопрос в настоящее время является то, что, когда я пытаюсь скомпилировать, терминал дает мне эту ошибку:.

SList.cpp :(текст + 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"; 
} 

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 

ответ

0

У вас есть циркуляр. slnode.h включает slist.h. slist.h включает slnode.h, который пропускается из-за включенных охранников. Поэтому, когда имя SNode встречается позже в slist.h, этот класс еще не объявлен, и вы получаете ошибку.

Поскольку заголовок slnode.h не использует ничего из slist.h, не включайте его. Альтернативой является использование class SList; для пересылки объявления класса.

+0

Благодарим Вас за быстрый ответ. Я удалил #include «SList.h» из моего файла SLNode.h, но это только что вызвало ошибку, которую я имел до этого, которая гласит: g ++ -o challenge-18 pc18.cpp SList.cpp SLNode.h /tmp/ccudaCGs.o: В функции 'SList :: ~ SList() ': SList.cpp :(. текст + 0x49): неопределенная ссылка на' SLNode :: ~ SLNode()' Приносим извинения за формат, я еще не знаю, как форматировать комментарии. –

0

Удалите #include заявление "SList.h" из файла SLNode.h. Это не нужно, и я думаю, что это вызывает ошибку.

0

Ваши привязки ссылаются друг на друга, а условное компиляция yo ввела означает, что либо SList, либо SLNode будут определены перед другим.

Изменение порядка включения или изменение условного компиляции не решит его - просто переместите проблему.

Вместо этого попробуйте сделать опережающее объявление вашей структуры/класса как этот

class SLNode; 
class SList { 
    .... 

и тот же непосредственно перед определением SLNode, сделать вышеописанную декларацию SList ..

+0

Благодарим за отзыв! Когда я взял #include «SList.h» из файла SLNode.h и перешел, как вы сказали мне, я все равно получаю сообщение об ошибке SList.cpp :(. Text + 0x49): неопределенная ссылка на 'SLNode :: ~ SLNode() '? вы думаете, что это может быть проблема с makefile? –

+0

Трудно сказать, не зная ваш make-файл и ваш модифицированный код, и включает в себя - вы должны задать новый вопрос, если у вас есть новая проблема – Soren