2

Я думаю, что неправильно использую свой шаблон, но я не могу понять, что я делаю неправильно. Это похоже на то, что связанный с шаблоном список не может понять, что он должен использовать мой класс Term.C++ Template Linked List Linker Error

theList-> insert (tempPolynomial); это строка кода, расположенная в конце функции.cpp, которая вызывает ошибку компоновщика!

Вот точные ошибки из Visual Studio 2012:

  • ошибка LNK2019: неразрешенный внешний символ "BOOL __cdecl оператор < (класс Term, класс LinkedList)" (?? M @ YA_NVTerm @@ V ? $ LinkedList @ VTerm @@@@@ Z) ссылка на функцию «public: void __thiscall LinkedList :: insert (класс Term)» (? Insert @? $ LinkedList @ VTerm @@@@ QAEXVTerm @@@ Z) C: \ Users \ Michael \ Documents \ Magic Портфель \ champlain \ courseWork \ dataStructures \ pa2 \ pa2 \ functions.obj

  • ошибка LNK1120: 1 неразрешенные внешние элементы C: \ Users \ Michae л \ Documents \ Волшебное портфель \ Чэмплэйн \ Курсовая \ dataStructures \ PA2 \ Debug \ pa2.exe

header.h

#include <iostream> 
#include <string> 
#include <stdlib.h> 
using namespace std; 

#include "linkedList.h" 
#include "term.h" 

void loadPolynomial(string expression, LinkedList<Term> *theList); 

functions.cpp

#include "header.h" 


void loadPolynomial(string expression, LinkedList<Term> *theList) 
{ 
    Term tempPolynomial; 

    string varDelimiter = "x"; 
    string posDelimiter = "+"; 
    string negDelimiter = "-"; 
    string token = ""; 

    double coefficient; 
    double exponent; 

    bool isNeg; 

    while(expression.length() > 0) 
    { 
     isNeg = false; 

     if(expression.substr(0, 1) == "+") 
     { 
      expression.erase(0, 1); 
     } 

     else if(expression.substr(0, 1) == "-") 
     { 
      isNeg = true; 
      expression.erase(0, 1); 
     } 

     //Get the coefficient 
     token = expression.substr(0, expression.find(varDelimiter)); 
     //Remove the coefficient and variable from the string leaving only the exponent 
     expression.erase(0, expression.find(varDelimiter) + varDelimiter.length()); 
     //Convert and put token's coeficient into a double 
     coefficient = atof(token.c_str()); 

     if(isNeg = true) 
     { 
      coefficient = coefficient * -1; 
     } 

     //Put the coefficient value into the tempPolynomial 
     tempPolynomial.setCoefficient(coefficient); 

     //If posDelimiter has a smaller length then it is the beginning of the next expression 
     if(expression.find(posDelimiter) < expression.find(negDelimiter)) 
     { 
      //Get the exponent 
      token = expression.substr(0, expression.find(posDelimiter)); 
      //Remove the exponent but leave the + 
      expression.erase(0, expression.find(varDelimiter)); 
      //Convert and put token's coeficient into a double 
      exponent = atof(token.c_str()); 
     } 

     else 
     { 
      //Get the exponent 
      token = expression.substr(0, expression.find(posDelimiter)); 
      //Remove the exponent but leave the + 
      expression.erase(0, expression.find(varDelimiter)); 
      //Convert and put token's coeficient into a double 
      exponent = atof(token.c_str()); 
     } 

     //Put the exponent value into the tempPolynomial 
     tempPolynomial.setExponent(exponent); 

     //Intert the first term into the linked list 
     theList->insert(tempPolynomial); 
    } 
} 

linkedList.h

#ifndef LINKED_LIST_H 
#define LINKED_LIST_H 

#include <iostream> 
#include <fstream> 
using namespace std; 

template <class T> 
class LinkedList 
{ 
private: 
    T mData; 
    LinkedList<T> *mNext; 

public: 
    LinkedList(); 
    LinkedList(T data); 
    ~LinkedList(); 

    T getData(); 
    LinkedList<T> *getNext(); 

    void setData(T data); 

    void display(); 
    void insert(T data); 
    bool isExist(T data); 
    void remove(T data); 

    friend ostream& operator<<(ostream &output, LinkedList<T> obj); 

    bool operator==(T right); 
    friend bool operator==(T left, LinkedList<T> right); 

    bool operator!=(T right); 
    friend bool operator!=(T left, LinkedList<T> right); 

    bool operator>(T right); 
    friend bool operator>(T left, LinkedList<T> right); 

    bool operator<(T right); 
    friend bool operator<(T left, LinkedList<T> right); 
}; 



template <class T> 
LinkedList<T>::LinkedList() 
{ 
    mNext = NULL; 
    mData = T(); 
} 



template <class T> 
LinkedList<T>::LinkedList(T data) 
{ 
    mNext = NULL; 
    mData = data; 
} 



template <class T> 
LinkedList<T>::~LinkedList() 
{ 
    LinkedList<T> *tempNode; 

    tempNode = mNext; 

    while(tempNode != NULL) 
    { 
     mNext = tempNode->mNext; 
     tempNode->mNext = NULL; 

     delete tempNode; 

     tempNode = mNext; 
    } 
} 



template <class T> 
T LinkedList<T>::getData() 
{ 
    return mData; 
} 



template <class T> 
LinkedList<T> *LinkedList<T>::getNext() 
{ 
    return mNext; 
} 



template <class T> 
void LinkedList<T>::setData(T data) 
{ 
    mData = data; 
} 



template <class T> 
void LinkedList<T>::display() 
{ 
    LinkedList<T> *tempNode; 

    tempNode = mNext; 

    while(tempNode != NULL) 
    { 
     cout << tempNode->mData << endl; 

     tempNode = tempNode->mNext; 
    } 
} 



template <class T> 
void LinkedList<T>::insert(T data) 
{ 
    LinkedList<T> *previousNode; 
    LinkedList<T> *tempNode; 
    LinkedList<T> *newNode; 

    newNode = new LinkedList(data); 

    if(mNext == NULL) 
    { 
     mNext = newNode; 
    } 

    else 
    { 
     previousNode = mNext; 
     tempNode = mNext; 

     while(tempNode != NULL && tempNode->mData < data) 
     { 
      previousNode = tempNode; 
      tempNode = tempNode->mNext; 
     } 

     if(tempNode == mNext) 
     { 
      newNode->mNext = mNext; 
      mNext = newNode; 
     } 

     else 
     { 
      previousNode->mNext = newNode; 
      newNode->mNext = tempNode; 
     } 
    } 
} 



template <class T> 
bool LinkedList<T>::isExist(T data) 
{ 
    LinkedList<T> *tempNode; 
    bool exist = false; 

    tempNode = mNext; 

    while(tempNode != NULL) 
    { 
     if(tempNode->mData == data) 
     { 
      exist = true; 

      break; 
     } 

     tempNode = tempNode->mNext; 
    } 

    return exist; 
} 



template <class T> 
void LinkedList<T>::remove(T data) 
{ 
    LinkedList<T> *tempNode; 
    LinkedList<T> *previousNode; 

    if(isExist(data) == false) 
    { 
     return; 
    } 

    tempNode = mNext; 
    previousNode = mNext; 

    while(tempNode->mData != data) 
    { 
     previousNode = tempNode; 
     tempNode = tempNode->mNext; 
    } 

    if(tempNode == mNext) 
    { 
     mNext = tempNode->mNext; 
     tempNode->mNext = NULL; 
    } 

    else 
    { 
     if(tempNode->mNext == NULL) 
     { 
      previousNode->mNext = NULL; 
     } 

     else 
     { 
      previousNode->mNext = tempNode->mNext; 
      tempNode->mNext = NULL; 
     } 
    } 

    delete tempNode; 
} 



template <class T> 
ostream& operator<<(ostream &output, LinkedList<T> obj) 
{ 
    output << obj.mData; 

    return output; 
} 



template <class T> 
bool LinkedList<T>::operator==(T right) 
{ 
    return mData == right; 
} 



template <class T> 
bool operator==(T left, LinkedList<T> right) 
{ 
    return left == right.mData; 
} 



template <class T> 
bool LinkedList<T>::operator!=(T right) 
{ 
    return mData != right; 
} 



template <class T> 
bool operator!=(T left, LinkedList<T> right) 
{ 
    return left != right.mData; 
} 



template <class T> 
bool LinkedList<T>::operator>(T right) 
{ 
    return mData > right; 
} 



template <class T> 
bool operator>(T left, LinkedList<T> right) 
{ 
    return left > right.mData; 
} 



template <class T> 
bool LinkedList<T>::operator<(T right) 
{ 
    return mData < right; 
} 



template <class T> 
bool operator<(T left, LinkedList<T> right) 
{ 
    return left < right.mData; 
} 

#endif 

term.h

#ifndef TERM_H 
#define TERM_H 

class Term 
{ 
private: 
    double mCoefficient; 
    double mExponent; 

public: 
    Term(); 
    Term(double coefficient, double exponent); 
    ~Term(); 

    double getCoefficient(); 
    double getExponent(); 
    void setCoefficient(double coefficient); 
    void setExponent(double exponent); 
}; 

#endif 
+0

Вы объявляете своих друзей, но вы все равно не определяете их. Итак ... определите их? – WhozCraig

+0

Я не уверен, что вы имеете в виду, поскольку реализованы все функции класса linkedList. Ошибка компоновщика возникает из-за этой строки кода: theList-> insert (tempPolynomial); – Angel

+0

Компоновщик утверждает следующее: 'bool __cdecl operator <(class Term, class LinkedList)' не найден. 'insert()' является * вызывающим *. Я вижу объявление в нижней части файла заголовка, поэтому теперь я не уверен, почему ваш шаблон не расширяется. В 'insert()' this: 'tempNode-> mData WhozCraig

ответ

0

Ваш класс Term требует меньшего компаратора. Любой из них будет делать:

В термине классе в качестве члена:

bool operator <(const Term&) const; 

Или свободной операторной функции:

bool operator <(const Term& left, const Term& right); 

Почему? Поскольку LinkedList<T>::insert(T val) вызывает следующее:

while(tempNode != NULL && tempNode->mData < data) 

Оба tempNode->mData и data имеют тип Term с вашим расширением шаблона. Но нет operator < (любая функция-член или свободная функция), которая сравнивает два объекта Term для "lesser".

Я не уверен, как вы хотите их сортировать (вероятно, сначала отсортируйте их по экспоненте, а коэффициент экспоненты - один и тот же). Я оставляю это до вас, но вам нужен оператор независимо.

ПримерTerm класса в качестве члена)

bool operator <(const Term& rhs) const 
{ 
    return (mCoefficient < rhs.mCoefficient || 
      (!(rhs.mCoefficient < mCoefficient) == && mExponent < rhs.mExponent)); 
} 

Пример II (свободный оператор, НЕ член Term)

bool operator <(const Term& lhs, const Term& rhs) 
{ 
    return (lhs.getCoefficient() < rhs.getCoefficient() || 
      (!(rhs.getCoefficient() < lhs.getCoefficient()) == && 
      lhs.getExponent() < rhs.getExponent())); 
} 

Примечание: если это подружился до Term вы можете получить доступ к членам напрямую, а не проходить через их функции getter (которые, кстати, должны быть объявлены const, поскольку они не вносят изменений в объект Term, на который они вызывают).

+0

Спасибо, что это сработало, и теперь это имеет смысл. Хотя я до сих пор не понимаю концепцию «свободного оператора». Является ли это общей функцией, которая переопределяет стандартный <оператор или что? – Angel

+0

@ user2045519 Я добавлю один ответ, и вы увидите разницу. Это будет очевидно. – WhozCraig

+0

Также почему так много сотен? – Angel