삶의 공유
[C++][Study] 내가 만드는 문자열 클래스(연산자오버로딩, 복사생성자) 본문
우리가 만든 MyString 문자열 클래스에 == 연산자 오버로딩하여 문자열 비교 기능을 추가해보자
연산자 오버로딩이란?
+, -, ==, [ ]와 같은 기본적으로 정의되어 있는 연산자 들을 우리의 입맛에 맞게 변형해서 사용할 수 있는것을 의미
operator 연산자 기본 구조는 다음과 같다.
"(리턴타입) operator (연산자)(연산자가 받는인자)"
변수 정의
1) char* string_content : 문자열 데이터를 가르키는 포인터
2) int string_length : 문자열 길이
3) int memory_capacity : 현재 할당된 용량
char* string_content;
int string_length;
int memory_capacity;
생성자 소멸자 정의
1) 'a', 'b' 이런 1개의 문자가 입력 되었을 때의 반응하는? 생성자이다.
즉, MyString('a') 와 같이 입력이 되면 이 생성자가 동작을 하게 된다.
MyString::MyString(char c){
string_content = new char[1];
string_content[0] = c;
memory_capacity = 1;
string_length = 1;
}
string_content의 포인터 변수에 동적 할당을 하여 메모리 공간을 가르키게 한다.
※new 키워드를 사용하여 동적으로 할당을 하게 되면 객체를 동적으로 생성하면서, 동시에 자동으로 생성자까지 호출해준다는 점!
그리고 그 변수 주소의 값에 c를 대입한다.
string_content = new char[1];
string_content[0] = c;
2) "abc", "hello" 와 같은 문자열 이 입력이 되었을 때 동작하는 생성자 이다.
즉, MyString("abc")와 같이 입력이 되면 이 생성자가 동작을 하게 된다.
인자만 포인터 변수로 받았을 뿐 문자만 입력 받는 생성자(1)와 동일하다.
MyString::MyString(const char* str){
string_length = strlen(str); // c 함수
memory_capacity = string_length;
string_content = new char[string_length];
for(int i = 0; i!= string_length; i++)
string_content[i] = str[i];
}
C 함수의 strlen함수를 써서 함수 인자 str의 길이에 대한 값을 리턴 받아 string_length변수에 대입한다.
그리고 그 크기 만큼 string_content 포인터 변수에 동적 할당을 한다.
string_length = strlen(str); // c 함수
memory_capacity = string_length;
string_content = new char[string_length];
3) 다음은 복사 생성자 이다.
복사 생성자는 표준 적인 정의라고 볼 수 있다.
기본적인 구조는 다음과 같다.
T(const T& a);
호출 방법은 다음과 같은데
- MyString str2(str1);
- MyString str2 = str1;
과 같이 할 경우 복사 생성자가 호출 되게 된다.
MyString::MyString(const MyString& str){
string_length = str.string_length;
string_content = new char[string_length];
for(int i =0; i!=string_length; i++)
string_content[i] = str.string_content[i];
}
여기서 중요한 점은 복사생성자 인자를 const 레퍼런스로 받았다는 점이다 ! 이 말은 이 인자의 값 자체는 변경할 수 가 없다는 뜻 !
4) 소멸자
생성자들을 통해서 동적할당되어 메모리를 차지하고 있는 포인터 변수들을 해제 해준다.
MyString::~MyString() { delete[] string_content; }
operator연산자와 compare 함수
나머지 함수들은 그리 어려운 부분이 없으니 바로 operator 연산자와 이것을 동작하게 해주는 compare함수만 다뤄보자
먼저 compare 함수 이다.
동작하는 방식은 다음과 같다.
현재 객체의 문자열 - 함수 인자의 문자열을 수행해서 1, 0, -1로 그 결과를 반환 한다는 의미이다.
: 1은 현재 객체의 문자열이 사전적으로 더 뒤에 온다는 의미
: 0은 두 문자열이 같다는 의미
: -1은 현재객체의 문자열이 사전적으로 더 앞에 온다는 의미
이것을 코드로 나타내면 다음과 같다
int MyString::compare(MyString& str){
// (*this) - (str) 을 수행해서 1,0,-1로 그 결과를 리턴한다
// 1은 (*this)가 사전적으로 더 뒤에 온다는 의미, 0은 두 문자열이 같다는 의미
// -1은 (*this)가 사전식으로 더 앞에 온다는 의미
for(int i = 0; i < std::min(string_length, str.string_length); i++){
if(string_content[i] > str.string_content[i])
return 1;
else if (string_content[i] < str.string_content[i])
return -1;
}
if(string_length == str.string_length) return 0;
// abc vs abcd의 크기 비교는 abcd가 더 뒤에 오게 된다.
else if (string_length > str.string_length)
return 1;
return -1;
}
먼저, for문을 이용해서 string_content와, str.string_content 포인터 변수의 문자열에 접근하다.
for(int i = 0; i < std::min(string_length, str.string_length); i++)
그리고 이렇게 문를 비교하여 사전적으로 어느 객체(현재객체 vs 인자)가 사전적으로 더 앞인지 뒤인지를 비교한다.
if(string_content[i] > str.string_content[i])
return 1;
else if (string_content[i] < str.string_content[i])
return -1;
여기까지 동일하면 이제 문자열 길이를 통해서 사전적으로 더 앞인지 뒤인지 구분한다.
즉, "abc" vs "abcd" 는 사전적으로 "abcd"가 뒤라는 의미 이다!
문자열이 같으면 이 2개의 문자는 같다는 뜻이다.
if(string_length == str.string_length) return 0;
else if (string_length > str.string_length)
return 1;
return -1;
자 이제 operator연산자 오버로딩을 이용할 차례이다.
자 함수의 리턴형태는 true, false로 리턴할 것이기 때문에 bool 형태로 정했다. 인자를 그대로 compare함수에 넘겨주기만 하면 된다!
bool MyString::operator==(MyString& str){
return !compare(str); // str과 같으면 comapre에서 0을 리턴한다
}
이렇게 정의한 것들을 어떻게 활용하는지 살펴보면 다음과 같다.
== 연산자를 이용하여 compare함수에 str인자를 넣어주어 호출하였다. 그리고 그 결과가 아래처럼 잘 나오는 것을 볼 수 있다.
int main()
{
MyString str1("a word");
MyString str2("sentence");
MyString str3("sentence");
if (str1 == str2)
std::cout << "str1와 str2는 같다" << std::endl;
else
std::cout << "str1와 str2는 다르다" << std::endl;
if (str2 == str3)
std::cout << "str2와 str3는 같다" << std::endl;
else
std::cout << "str2와 str3는 다르다" << std::endl;
return 0;
}
결과)
자 이렇게 우리가 만든 문자열 클래스를 이용하여 복사 생성자, 생성자에 대한 복습과 새로 나온 개념에 대한 operator 연산자 오버로딩에 대해서도 학습했다.
앞으로 C++ 학습의 길은 멀고도 험하지만, 차근차근히 해내보자! 뭐든지 꾸준함이 제일 중요하니...
[reference]
'Programing > C++' 카테고리의 다른 글
[C++] 표준 입출력 (1) | 2024.01.31 |
---|---|
[C++] Pointer(포인터)[상] (0) | 2021.12.25 |
[C++][Study] 내가 만드는 String 문자열 (0) | 2021.12.16 |
Xcode & SFML 셋팅하기 (0) | 2021.07.07 |
[C++] C++와 표준 라이브러리 초단기 속성코스(포인터, 참조, const, 타입추론) (0) | 2021.02.03 |