string 클래스를 모델로 삼아서 연산자가 어떠한 형태로 오보러딩 되어 있는지 보고, 이와 유사한 문자열 처리 클래스를 직접 구현해 보는데 목적이 있습니다. 이는 표준 string 클래스를 사용하는 것 이상의 의미가 있다고 생각합니다.
#pragma warning(disable:4996) #include <iostream> #include <string> using namespace std; int main(void) { string str1 = "I like "; string str2 = "string class"; string str3 = str1 + str2; cout << str1 << endl; cout << str2 << endl; cout << str3 << endl; str1 += str2; if (str1 == str3) cout << "same" << endl; else cout << "not same" << endl; string str4; cout << "charcter string input: "; cin >> str4; cout << "string output: " << str4 << endl; return 0; } |
string 객체간 덧셈연산이 가능함을 알 수 있습니다. 이는 operator + 연산자의 오버로딩으로 인해 가능합니다. string 클래스가 << 연산자에 대해서도 오버로딩 되어있음을 확인 할 수 있습니다.
문자열 처리 클래스의 정의
요구사항들에 대해서 정의해보도록 하겠습니다. 문자열을 인자로 전달받는 생성자의 정의. 생성자, 소멸자 복사 생성자 그리고 대입 연산자의 정의가 필요합니다. 결합된 문자열로 초기화된 객체를 반환하는 + 연산자의 오버로딩 + 연산자의 반환 값은 다음 두 가지입니다. 문자열의 주소 값(str1고 str2가 지니고 있는 무자열을 합한 문자열의 주소 값) 그리고 string 객체(str1과 str2가 지니고 있는 문자열을 합한 문자열을 저장하고 있는 객체입니다.) 내용비교를 진행하는 == 연산자의 오버로딩.
문자열을 입력 받을 목적으로, 다음의 형태로 객체를 생성할 수 있게 하기 위해서 정의된 생성자입니다. String emptystr; 때문에 멤버변수 str에는 NULL이 저장될 수도 있습니다. 그래서 멤버변수 str을 대상으로 delete 연산을 하기에 앞서, str에 저장된 값이 NULL인지를 검사하는 코드를 소멸자를 포함해서 곳곳에서 확인할 수 있습니다.
#pragma warning(disable:4996) #include <iostream> #include <cstring> using namespace std; class String { private: int len; char * str; public: String(); String(const char * s); String(const String& s); ~String(); String& operator = (const String& s); String& operator+= (const String& s); bool operator== (const String& s); String operator+ (const String& s); friend ostream& operator<< (ostream& os, const String& s); friend istream& operator >> (istream& is, String& s); }; String::String() { len = 0; str = NULL; } String::String(const char* s) { len - strlen(s) + 1; str = new char[len]; strcpy(str, s); } String::String(const String& s) { len = s.len; str = new char[len]; strcpy(str, s.str); } String::~String() { if (str != NULL) delete[]str; } String& String::operator= (const String& s) { if (str != NULL) delete[]str; len = s.len; str = new char[len]; strcpy(str, s.str); return *this; } String& String::operator+= (const String& s) { len += (s.len - 1); char* tempstr = new char[len]; strcpy(tempstr, str); strcat(tempstr, s.str); if (str != NULL) delete[]str; str = tempstr; return *this; } bool String::operator == (const String& s) { return strcmp(str, s.str) ? false : true; } String String::operator+ (const String& s) { char* tempstr = new char[len + s.len - 1]; strcpy(tempstr, str); strcat(tempstr, s.str); String temp(tempstr); delete[]tempstr; return temp; } ostream& operator<< (ostream& os, const String& s) { os << s.str; return os; } istream& operator >> (istream& is, String& s) { char str[100]; is >> str; s = String(str); return is; } int main(void) { String str1 = "I like "; String str2 = "string class"; String str3 = str1 + str2; cout << str1 << endl; cout << str2 << endl; cout << str3 << endl; str1 += str2; if (str1 == str3) cout << "same" << endl; else cout << "not same" << endl; String str4; cout << "Input: "; cin >> str4; cout << "Output: " << str4 << endl; return 0; } |
main 함수는 앞소 소개한 예제의 main 함수와 동일합니다. 다만 표준 string 클래스를 대신해서 우리가 정의한 String 클래스를 사용한 것이 유일한 차이점입니다.