2014-11-06 2 views
0

두 개의 연결된 목록을 함께 추가하려면 '+'연산자를 오버로드하는 데 도움이 필요합니다. "no operator for ... ="오류로 인해 프로그램을 컴파일 할 수 없습니다. 나는 '='연산자를 이미 오버로드했지만 std 출력에 추가 된 결과를 출력하는 데 어려움을 겪고 있습니다. 또한 < < 연산자를 오버로드했습니다. 성공하지 못한 채 몇 시간 동안 잘못되었는지 알아 내려고 노력했습니다. 이 문제를 해결하는 방법 및/또는 솔루션에 대한 모든 힌트를 매우 환영합니다. 내 OOP 클래스에 대한 할당입니다. 미리 감사드립니다.두 개의 이중 연결된 목록을 추가하기위한 연산자 오버로드

편집 : 코드의 기본 아이디어는 세트를 복제하는 것입니다. 오버로드 된 연산자 '+'는 공용체로 작동하고 '*'는 교차로로 사용해야합니다. 나는 노동 조합이 표준 산출물에 제대로 인쇄되도록하기 위해 고투한다. '+ ='잘 작동하는 것 같습니다. '< <'은 잘 작동하지만 단 한 개의 목록을 인쇄 할 때만 작동합니다.


편집 : 컴파일러에 의해 생성 오류 (g ++ 코드에서 출력 :: 블록, 내가 제거한 컴파일러 노트) :

llist3.cpp|149|error: no match for ‘operator=’ (operand types are ‘LList’ and ‘LList’)| 
llist3.cpp|106|note: no known conversion for argument 1 from ‘LList’ to ‘LList&’| 
llist3.cpp|151|error: no match for ‘operator=’ (operand types are ‘LList’ and ‘LList’)| 
llist3.cpp|106|note: no known conversion for argument 1 from ‘LList’ to ‘LList&’| 
llist3.cpp|152|error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka  std::basic_ostream<char>}’ and ‘LList’)| 
하나의 눈부신 오류
#include<iostream> 
using namespace std; 

class LList { 
public: 
    struct Node { 
     int elem; 
     Node* succ; 
     Node* prev; 
     Node() : succ(0), prev(0), elem(0) {} 
    }; 
    LList(); 
    LList(LList& list); 
    ~LList(); 

    Node* next(); 
    Node* begin() { curr = head; } 

    int getElem() { return curr->elem; } 
    void addElem(int elem); 
    LList operator+(LList& set); 
    LList operator+(int elem); 
    LList& operator+=(LList& set); 
    LList& operator+=(int elem); 
    LList& operator=(LList& list); 
    friend ostream& operator<<(ostream& os, LList& obj); 
private: 
    Node* curr; 
    Node* head; 
    Node* tail; 
    int size; 
    void pushFront(Node* n); 
    void pushInside(Node* n); 
    void pushBack(Node* n); 
}; 

LList::LList() : head(0), tail(0), size(0), curr(0) {} 
LList::LList(LList& list) : size(0), curr(0), head(0), tail(0) { 
    list.curr = list.head; 
    while(list.curr) { 
     addElem(list.getElem()); 
     list.next(); 
    } 
} 
LList::Node* LList::next() { 
    if (curr) 
     return (curr = curr->succ); 
    else 
     return 0; 
} 
void LList::addElem(int elem) { 
    Node* n = new Node; 
    n->elem = elem; 
    if (curr) { 
     if (curr == head && elem < curr->elem) { 
      pushFront(n); 
     } 
     else if (elem > curr->elem) { 
      curr = curr->succ; 
      addElem(elem); 
     } 
     else if (elem < curr->elem && elem > (curr->prev)->elem) { 
      pushInside(n); 
     } 
     else if (elem < curr->elem) { 
      curr = curr->prev; 
      addElem(elem); 
     } 
    } else { 
     pushBack(n); 
    } 
} 
void LList::pushFront(Node* n) { 
    head = n; 
    n->succ = curr; 
    curr->prev = n; 
    n->prev = 0; 
    curr = n; 
    size++; 
} 
void LList::pushInside(Node* n) { 
    (curr->prev)->succ = n; 
    n->succ = curr; 
    n->prev = curr->prev; 
    curr->prev = n; 
    size++; 
} 
void LList::pushBack(Node* n) { 
    if (!head) { 
     head = n; 
    } else { 
     tail->succ = n; 
     n->prev = tail; 
    } 
    tail = n; 
    curr = n; 
    size++; 
} 
LList::~LList() { 
    for (curr = head; curr;) { 
     Node* temp = curr->succ; 
     delete curr; 
     curr = temp; 
    } 
} 
LList& LList::operator=(LList& list) { 
    list.begin(); 
    if (this != &list) { 
     for (curr = head; curr;) { 
      Node* temp = curr->succ; 
      delete curr; 
      curr = temp; 
     } 
     while (list.curr) { 
      addElem(list.getElem()); 
      list.next(); 
     } 
    } 
    return *this; 
} 
ostream& operator<<(ostream& os, LList& list) { 
    LList::Node* p = list.head; 
    os << "{ "; 
    while(p) { 
     os << p->elem << (p->succ ? ", " : ""); 
     p = p->succ; 
    } 
    os << " }" << endl; 
    return os; 
} 
LList LList::operator+(LList& set) { 
    LList temp = *this; 
    temp += set; 
    return temp; 
} 
LList LList::operator+(int elem) { 
    *this += elem; 
    return *this; 
} 
int main() { 
    LList setA; 
    setA.addElem(1234); 
    setA.addElem(1435); 
    setA.addElem(1100); 
    LList setB; 
    setB.addElem(1234); 
    setB.addElem(1435); 
    setB.addElem(5100); 
    setB = setA + 1234; // 1st error here 
    LList setD; 
    setD = setA + setB; //2nd 
    cout << setA + setB << endl; //3rd 
} 
+5

TL; 문제가있는 부분 만 코드 범위를 좁혀주십시오. 가장 좋은 방법은 [Minimal, Complete, Verifiable example] (http://stackoverflow.com/help/mcve)을 작성하여 표시하는 것입니다. 또한 폴란드 인 (?)을 읽는 사람들이 많이 없으므로 의견을 말하고 영어로 출력하십시오. –

+0

죄송합니다. 처음으로 여기에 게시했습니다. 가능한 빨리 업데이트 할 것입니다. –

+0

절차는 다음과 같습니다. 코드를 10-100 줄 정도의 소스 파일 하나와 비교하여 도움을 받고자하는 오류가 계속 발생하는지 확인한 다음 소스 파일 **을 전체적으로 게시하십시오 편집하지 않고 **. ** 수정되지 않은 ** 오류 메시지 (또는 목록이 너무 길면 몇 줄을 포함)를 포함하는 것을 잊지 마십시오. 게시 한 내용을 그대로 복사하여 도움을 받으려는 오류와 똑같은 오류가 발생하면 모든 사람의 시간을 낭비하게됩니다. –

답변

0

목록 클래스에 "현재"포인터가 내장되어 있습니다. 이것은 심각한 설계 오류입니다. 이 오류로 인해 함수를 올바르게 정의 할 수 없습니다.

이 디자인을 사용하면 const 목록을 반복 할 수 없으므로 이것은 다른 나쁜 것들 중에서도 임시 목록과 관련하여 유용한 것을 할 수 없기 때문에 디자인 오류입니다.따라서 setA + setB을 계산할 때 반복 할 필요가 있으므로 할당하지 않으려면 operator=의 비 const 인수와 복사 생성자가 필요하므로 아무 것도 할당 할 수 없습니다. 하지만 임시가 아닌 const 참조에 바인딩 할 수 없습니다.

복사 생성자와 복사 할당 연산자에서 공용 인터페이스를 무시하고 curr을 사용하지 않고 목록을 직접 복사하더라도 공용 인터페이스를 사용해야하는 모든 사용자 함수에서 동일한 문제가 발생합니다. 즉, setA + setB은 함수 인수로 사용할 수 없습니다. 변수를 먼저 변수에 할당 한 다음 해당 변수를 함수에 전달해야합니다.

목록을 반복하여 일부 기능으로 전달할 수없고 목록을 반복하는 항목이 curr 포인터를 변경하기 때문에 왼쪽에서 계속해서 반복 할 수 있습니다.

최상의 해결책은 curr 회원을 없애고 대부분의 인수를 const LList&으로 만드는 것입니다. 이것이 괄목할만한 해결책은 아니지만 현재 포인터를 목록 클래스에 포함시키는 데있어 다른 많은 단점이 있으므로 필자는 그것에 대해 이야기하지 않을 것이다.

목록을 반복하려면 목록에서 앞뒤로 이동할 수있는 별도의 개체와 const 목록을 통해 앞뒤로 이동할 수있는 별도의 개체를 제공해야합니다. 이것은 이터레이터이라고하며, C++에서 무엇인가하고 싶다면이 개념을 읽어야합니다.

경우에 따라 반복기는 Node*const Node* 일 수 있습니다. 이미 가지고있는 목록의 첫 번째 노드를 반환하는 멤버 함수 만 제공하면됩니다. 실제 라이브러리도 똑같습니다. 그들은 일반적으로 여러 가지 이유로 노드 포인터를 별도의 반복자 클래스로 래핑합니다. 하지만 간단한 숙제를 원할 경우에는 필요하지 않습니다.

2

있다 귀하의 코드 :

Node* begin() { curr = head; } 

이 코드는 값을 반환하지 않으므로 정의되지 않은 동작을 호출합니다.

LList::LList(LList& list); 
LList& operator=(LList& list); 
friend ostream& operator<<(ostream& os, LList& obj); 

가 있어야한다 : 예를 들어

:

Node* begin() { curr = head; return curr; } 

또한, 당신은 LList 매개 변수를 변경하지 않는 기능에 const를 참조하여 LList을 통과해야합니다 : 그것은이 있어야한다 :

LList::LList(const LList& list); 
LList& operator=(const LList& list); 
friend ostream& operator<<(ostream& os, const LList& obj); 

다른 fu const 참조 전달.

LList list1; 
LList list2; 
//... 
std::cout << list1 + list2; 
operator <<는 const가 아닌 LList 개체를 찾고

하지만, 또한 "인라인"는를 반환 : 당신은 당신이이 설정을 변경해야하는 이유를보고 싶은 경우에, 당신은이 작업을 수행하려고하면 즉시 문제를 볼 수 있습니다 임시 LList (이는 반환 값이 const임을 의미합니다). 코드가 컴파일되지 않습니다 operator <<은 비 const LList만을 허용합니다.

operator <<의 매개 변수를 const LList&으로 변경해야합니다.

+0

operator +를 friend 함수로 구현하는 것도 좋습니다. – besworland

+0

폴 감사합니다. 문제 해결, 함수에 전달 된 매개 변수에 const 추가. 당신의 도움을 주셔서 감사합니다! –

+0

@besworland 왜 더 좋을지 자세한 정보를 제공해 주시겠습니까? –