이전 질문 게시판은 새 글 쓰기를 막았습니다. [질문 게시판]을 이용바랍니다.
Date |
2008/09/23 00:32:20 |
Name |
EZrock |
Subject |
C++ 연산자 오버로딩 질문 |
일단 문제 내용은 이렇습니다. 숫자형의 스트링을 2개 입력받아서 더해 실제 계산 결과처럼 만드는 것이 목적입니다.
그것을 위해 연산자 오버로딩을 사용하는 건데...
...뭐랄까 일단 객체1의 스트링을 저장하는 멤버 변수 값에 12345678901234567890 객체 2의 변수 값에 987654321987654321을 입력하고
객체3 = 객체1 + 객체2; 를 하면 저 두개의 스트링을 더하는 값을 출력하게 하는 것입니다.
함수가 좀 더럽게 된 편이지만 일단 만들긴 했는데... 왠지 +연산 오버로딩이 안된 느낌입니다.
마치 객체3 = 객체1 정도만 인식되는 느낌...?
약간 더러운 소스를 보여드려 죄송합니다;;
class StrInt { // 클래스 선언
char *StrToInt; // 숫자형의 문자열을 저장할 char * 타입의 문자열
int Length; // 문자열 길이 즉 자리수
public:
StrInt();
StrInt(string _str);
StrInt(const StrInt& s);
~StrInt();
StrInt& operator=(const StrInt& s);
StrInt& operator+(const StrInt& s);
void Print();
};
StrInt& StrInt::operator +(const StrInt &s)
{
bool Flag = false; // 합하여 10을 넘기면 true 아니면 false
int Length1 = strlen(StrToInt); // 첫번째 객체에 저장된 스트링의 길이
int Length2 = s.Length; // 두번째 객체에 저장된 스트링의 길이
int Length; // Result의 길이
char *Result; // 합산한 결과를 가질 스트링[캐릭터 배열 타입으로 썼습니다.]
// 밑의 두 캐릭터배열은 원래 스트링이 const로 묶여 있어서 자리수가 다를경우 0을 채워 맞출 필요가 있기 때문에 새로 생성
char *StrToInt2 = new char[Length2+1]; // 첫번째 스트링을 이어받을 캐릭터 배열
strcpy(StrToInt2, StrToInt); // s1 객체의 스트링을 복사 ... 사실 이 방법도 책을 그대로 베껴서 맞을지도 의문 입니다.
char *s2 = new char[Length1+1]; // 두번째 스트링을 이어받을 캐릭터 배열
strcpy(s2, s.StrToInt); // s2 객체의 스트링을 복사
if(Length1 > Length2) { // 객체1의 스트링 길이가 객체2의 스트링 길이보다 길경우 s2의 길이를 늘리고 앞은 0으로 채운다.
delete [] s2; // 길이가 짧으므로 일단 메모리 해제
Length = Length1;
Result = new char[Length+2]; // Result의 길이는 제일 앞자리 연산 결과가 10을 넘을수 있으므로 +2
s2 = new char[Length+1]; // s2 재설정 나머지 공간은 0으로 채우기
for(int x = Length-1 ; x>=0; x--){ // xxxxx+xxx의 경우 xxxxx+00xxx로 맞추기 위해 뒤에서 부터 복사
if((Length2-1) - x <= 0) s2[x] = s.StrToInt[x];
else s2[x] = '0';
}
/* 바로 위쪽 for문의 아이디어는 Length2는 s2의 길이가 갖쳐져 있기 때문에 ex)3
(Length2-1)값 즉 2에서 4~0까지 가며 뺀 값이 0보다 작거나 같은 경우는 4,3,2
이 세번의 경우에는 인덱스 뒤에서 부터 채운다. 자리수와 맞아 떨어진다.
그 외의 케이스 0,1의 경우에는 s2인덱스 0번 1번에 '0'으로 채운다. */
}
else if(Length1 < Length2) {
delete [] StrToInt2;
Length = Length2;
Result = new char[Length+2];
StrToInt2 = new char[Length+1];
for(int y = Length-1; y>=0; y--){
if((Length1-1) - y <= 0) StrToInt2[y] = s.StrToInt[y];
else StrToInt2[y] = '0';
}
}
else if(Length1 == Length2) { // 두개의 길이 즉 자리수가 같으면 Length에는 아무 길이나 던져주고
Length = Length1;
Result = new char[Length+2]; // Result는 Null 포함 1자리 더 붙인 자리수로 배열을 만든다.
}
for(int i = Length-1; i>=0; i--){ // 배열 가장 끝에서 부터 접근
int Number1 = s2[i]-'0'; // Number1의 변수에는 s2배열의 i번째 인덱스의 숫자형 문자를 int로 바꿔준다.
int Number2 = StrToInt2[i]-'0'; // 마찬가지로 StrToInt2 배열의 i번째 인덱스 문자를 int로 atoi는...문자열만 가능
int Sum = Number1+Number2; // 두 수를 더한다.
if(Flag) { // 어떤 자리에 더해서 10을 넘긴 수가 있으면
Flag = false;
Sum = Sum + 1; // 2+6+1(올라온 10) 이런식으로 더한다.
}
if(Sum >=10 ){ // Sum이 10을 넘으면
Flag = true; // 올라갈 자리수가 있다고 표시해주고
Result[i-1] = Sum - 10 +'0'; // 10을 넘었으니 10을 빼고 캐릭터화
} /* [][][][][][][] 즉 0~length-1까지 채우고 length-1의 주소에는 null이 들어가야 하므로
<-표시공간-> null length-2 즉 i-2부터 채워나간다. */
else Result[i-1] = Sum + '0'; // 그냥 캐릭터화
// 마지막 체크
if(i==0 && Flag == true) Result[0] = '1'; // xxxxx+00xxx에서 제일앞의 x와 0의 합이 10을 넘으면
// Result배열 제일 앞에 문자 1을 넣어준다.
else Result[0] = '0'; // 그렇지 않으면 0을 넣는다.
}
Result[Length-1] = NULL; // 마지막 공간에 널 삽입
delete [] s2; // s2와 StrToInt는 임시용이었으므로 해제.
delete [] StrToInt2;
return *this;
}
...뭐 이런식으로 짰습니다만...채우는 부분이 좀 지저분 하기도 하고 이래저래 안달린 주석쓰면서 고쳐보기도 해서 만든 최종판이 이것인데...
여전히 문제점은 존재합니다.
오버로딩이 익숙치 않은데다가 이런식의 오버로딩은 아이디어는 단순할 줄 알았는데 해보니까 여기저기 문제점이 많더군요.
많이 도와주셨으면 합니다.
...이것 외에도 빼기 연산자 오버로딩까지 해야해서...
참 답답합니다...ㅠ_ㅠ
|
통합규정 1.3 이용안내 인용
"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.
법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
|