원형리스트 덧셈하는건데요..
글쓴이: 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.
댓글 달기