원형리스트 덧셈하는건데요..
글쓴이: widgie / 작성시간: 목, 2005/11/03 - 12:52오전
우선 숙제임을 밝혀둡니다 -_-;;
하다하다 도저히 막혀서 이렇게 올리네요
코드는 아래와 같습니다.
다항식 2개를 입력받아
연산자 오버로딩으로
두 다항식의 합을 출력하는건데
vc6 에서 컴파일 했을 경우
두 다항식의 입력과 출력은 되는데
그 합을 출력하는 부분에서 멈춰버립니다.
며칠밤을 고민했는데도 도대체 뭐가 문제인지
감이 안 잡힙니다. 도움 좀 주세요 :oops:
#include <iostream.h> struct Term { int exp; int coef; void Init(int c, int e){coef = c; exp = e;}; }; class List; class CircListIterator; class ListNode { friend class List; friend class CircListIterator; public: ListNode(Term k) { data = k; link = 0; }; private: Term data; ListNode *link; }; class List { friend class CircListIterator; public: void Attach(Term k); List() { first = 0; last = 0; }; ~List(); private: ListNode *first; ListNode *last; ListNode *head; }; List::~List() { ListNode* next; ListNode* now; now = head; next = head; while(true){ next = next->link; delete now; if(next == NULL) break; now = next; } } void List::Attach(Term k){ ListNode *newnode = new ListNode(k); if(first==0){ Term a; a.Init(0,-1); ListNode *node = new ListNode(a); first = newnode; last = newnode; head = node; head->link = first; newnode->link = head; } else { last->link = newnode; newnode->link = head; last = newnode; } } class CircListIterator { public: CircListIterator(const List& l):list(l), current(l.first){}; bool NotNull() { if(current) return true; else return false; }; bool NextNotNull() { if(current && current->link) return true; else return false; }; Term* First() { if(list.first) return &list.first->data; else return 0; } Term* Next() { current = current->link; return ¤t->data; }; private: const List& list; ListNode* current; }; class Polynomial{ private: List poly; public: Polynomial(){}; Polynomial(const Polynomial &); friend Polynomial operator+(const Polynomial&, const Polynomial&); friend istream& operator>>(istream&, Polynomial&); friend ostream& operator<<(ostream &, const Polynomial &); }; Polynomial::Polynomial(const Polynomial &a){ Term *p, *q, temp; CircListIterator iter(poly); CircListIterator iter2(a.poly); p = iter.First(); q = iter2.First(); while (iter.NotNull()) { temp.Init(0,-1); poly.Attach(temp); p = iter.Next(); } while (iter2.NotNull()) { temp.Init(q->coef,q->exp); poly.Attach(temp); q = iter2.Next(); } } char compare(int x, int y) { if(x == y) return '='; else if(x < y) return '<'; else return '>'; } Polynomial operator+(const Polynomial& a, const Polynomial& b){ Term *p, *q, temp; CircListIterator Aiter(a.poly); CircListIterator Biter(b.poly); Polynomial c; p = Aiter.First();q = Biter.First(); while(1) switch( compare(p->exp, q->exp) ) { case '=': if( p->exp == -1 ) return c; else { int sum = p->coef + q->coef; if(sum) { temp.Init(sum, q->exp); c.poly.Attach(temp); } p = Aiter.Next(); q = Biter.Next(); } break; case '<': temp.Init(q->coef, q->exp); c.poly.Attach(temp); q = Biter.Next(); break; case '>': temp.Init(p->coef, p->exp); c.poly.Attach(temp); p = Aiter.Next(); break; } } istream& operator>>(istream& is, Polynomial& p){ Term temp; int exp; int coef; char ch = ' '; while( ch != '\n') { is >> coef >> exp; temp.Init(coef, exp); p.poly.Attach(temp); ch = is.get(); } return is; } ostream& operator<<(ostream & os ,const Polynomial & a) { Term *p; CircListIterator iter(a.poly); p = iter.First(); while(!((p->exp) == -1)){ if( p->coef > 0 && p!=iter.First() ) cout << " + "; cout << p->coef << "x^" << p->exp ; p = iter.Next(); } cout << endl; return os; } int main() { Polynomial A,B,C; cout <<"입력 예제 : 3x^14 + 2x^8 - 7x^3 + 1 -> 3 14 2 8 7 3 1 0 "<<endl; cout <<"\n A 다항식 : "; cin >> A; cout <<"\n B 다항식 : "; cin >> B; cout<<endl; cout<<"A = "<<A<<endl; cout<<"B = "<<B<<endl; C = A + B; cout<<"C = "<<C<<endl; return 0; }
Forums:
[code:1]C = A + B; [/code:1]여기서 A+B
C = A + B;
여기서 A+B의 결과는
Polynomial operator+(const Polynomial& a, const Polynomial& b)
에서 계산됩니다.
그리고 opeartor+ 안에서는
if( p->exp == -1 ) return c;
로 리턴합니다.
그러면 말이죠...
C = A + B 에서 이번엔 operator= 가 호출될 차례입니다.
그런데, Polynomial내의 List에는 operator=가 정의되지 않았습니다.
따라서! bitwise로 그냥 내용을 복사합니다.
(비트 단위로 그냥 복사되므로, 같은 내용을 가리키는 포인터가 2개)
그런데 return c에서 c는 지역변수이므로 그 내용이 파괴됩니다.
그러면서 그 멤버인 List의 소멸자를 호출하고, 따라서 리스트는
파괴됩니다.
결국 복사한 것은 쓸모가 없게 된거죠...
다시 말해서
c.List -> 0x1
반환값 -> 0x1
이라는 같은 주소를 가리키다가
c.List-> null
반환값-> 0x1 (c가 소멸하면서 이 주소내의 list는 이미 파괴됨.)
해결책은, 동적으로 할당하는 메모리에서는 언제나 복사 생성자와 operator=를 같이 정의하라는 것입니다.
--
Passion is like genius; a miracle.
댓글 달기