Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

nomad-programmer

[Programming/C++] 표준 string 클래스의 분석 본문

Programming/C++

[Programming/C++] 표준 string 클래스의 분석

scii 2021. 2. 6. 21:12

C++ 표준 라이브러리에는 string이라는 이름의 클래스가 정의되어 있다. 해당 클래스는 문자열의 처리를 목적으로 정의된 클래스이며, 이 클래스의 사용을 위해서는 헤더파일 <string> 을 포함해야 한다.

#include <iostream>
#include <string>

usging namespace std;

int main(void) {
  string str1 = "C++ ";
  string str2 = "Language Love";
  string str3 = str1 + str2;
  
  cout << str1 << endl;
  cout << str2 << endl;
  cout << str3 << endl;
  
  str1 += str2;
  if(str1 == str3) {
    cout << "동일한 문자열" << endl;
  }
  else {
    cout << "동일하지 않은 문자열" << endl;
  }
  
  string str4;
  cout << "문자열 입력: ";
  cin >> str4;
  cout << "입력한 문자열: " << str4 << endl;
  
  return 0;
}

위의 예제를 보면 <string> 헤더파일을 추가하고 있다. 이 라이브러리로 인하여 C# 혹은 Python언어에서 자주 보던 문자열 연산을 진행할 수 있다.


문자열 처리 클래스의 정의

#include <iostream>
#include <cstring>

#pragma warning(disable: 4996)

using std::cout;
using std::cin;
using std::endl;


class String {
private:
    char* str;
    int len;

public:
    String(void);
    String(const char* str);
    String(const String& ref);
    ~String();
    String& operator=(const String& ref);
    String operator+(const String& ref);
    String& operator+=(const String& ref);
    bool operator==(const String& ref);

    friend std::ostream& operator<<(std::ostream& os, const String& ref);
    friend std::istream& operator>>(std::istream& is, String& ref);
};

String::String() : str(nullptr), len(0) {};

String::String(const char* str) : len(strlen(str) + 1) {
    this->str = new char[len];
    strcpy(this->str, str);
}

String::String(const String& ref) : len(ref.len) {
    str = new char[len];
    strcpy(str, ref.str);
}

String::~String() {
    if (str == nullptr) {
        return;
    }
    delete[] str;
}

String& String::operator=(const String& ref) {
    if (str != nullptr) {
        delete[] str;
    }
    len = ref.len;
    str = new char[len];
    strcpy(str, ref.str);
    return *this;
}

String String::operator+(const String& ref) {
    int len = this->len + ref.len - 1;
    char* tmp = new char[len];
    strcpy(tmp, str);
    strcat(tmp, ref.str);
    String strTemp(tmp);
    delete[] tmp;
    return strTemp;
}

String& String::operator+=(const String& ref) {
    len += (ref.len - 1);
    char* strTemp = new char[len];
    strcpy(strTemp, str);
    strcat(strTemp, ref.str);
    if(str != nullptr){
        delete[] str;
    }
    str = strTemp;
    return *this;
}

bool String::operator==(const String& ref) {
    return strcmp(str, ref.str) ? false : true;
}

std::ostream& operator<<(std::ostream& os, const String& ref) {
    os << ref.str;
    return os;
}

std::istream& operator>>(std::istream& is, String& ref) {
    char tmp[100];
    is >> tmp;
    ref = String(tmp);
    return is;
}


 int main(const int argc, const char* const argv[]) { 
     String str1 = "I like ";
     String str2 = "string class";
     String str3 = str1 + str2;
     cout << str1 << endl;
     cout << str2 << endl;
     cout << str3 << endl;
     str1 += str2;
     cout << str1 << endl;
     if (str1 == str3) {
         cout << "동일 문자열!" << endl;
     }
     else {
         cout << "동일하지 않은 문자열!" << endl;
     }
     String str4;
     cout << "문자열 입력: ";
     cin >> str4;
     cout << "입력한 문자열: " << str4 << endl;

     return 0;
}

/* 결과

I like
string class
I like string class
I like string class
동일 문자열!
문자열 입력: test_string
입력한 문자열: test_string

*/

operator+ 연산자 오버로딩된 메소드를 살펴보자.

+ 연산자는 원래 새로운 값을 만들어 내는 연산자이지, 피연산자의 값ㅇ르 변경시키는 연산자가 아니다. 그래서 위의 함수에서도 피연산자의 문자열 정보를 참조해서 새로운 객체를 만들어 반환하고 있다.

String& String::operator+=(const String& ref) {
    len += (ref.len - 1);
    char* strTemp = new char[len];
    strcpy(strTemp, str);
    strcat(strTemp, ref.str);
    if(str != nullptr){
        delete[] str;
    }
    str = strTemp;
    return *this;
}

위의 함수는 다음과 같이 간단하게도 정의가 가능하다.

String& String::operator+=(const String& ref) {
    *this = *this + ref;
    return *this;
}

이러한 형태의 정의는 간결해 보이고 이해하기도 좋지만, 덧셈의 과정에서 객체가 추가로 생성된다는 단점이 있다. 하지만 컴퓨팅 파워가 좋은 환경이라면 이 정도는 단점이 될 수 없으니, 이러한 형태의 구현도 생각해볼 만하다.

Comments