반응형
안녕하세요? 수구리입니다.
저번 포스팅에서는 C 스타일의 string에 대해서 알아보았었습니다.
2021.08.24 - [C++] - [C++] 동적 스트링 Part 1
이번 포스팅에서는 이어서 C++의 string 클래스에 대해서 알아보도록 하겠습니다!
2.1.3 C++ std::string 클래스
- <cstring> 의 함수와 기능은 비슷하지만 메모리 할당 작업을 처리해주는 기능이 들어있다.
- string 클래스는 std 네임스페이스에 속하며 헤더에 정의되어 있다.
C 스타일 스트링의 장단점
- 장점
- 간단함. 내부적으로 기본 문자 타입과 배열 구조체로 처리
- 가볍다. 제대로 사용하면 메모리를 꼭 필요한 만큼만 사용
- 로우 레벨이다. 메모리의 실제 상태를 조작 및 복사가 쉽다
- C 프로그래머에 익숙하다.
- 단점
- 스트링 데이터 타입에 대한 고차원 기능을 구현하려면 노력 필요
- 찾기 힘든 메모리 버그 발생
- C++의 객체 지향적인 특성을 제대로 활용 못함
- 프로그래머가 내부 표현 방식을 이해필요!
- C++의 string은 C 스타일의 스트링이 가진 장점은 유지하면서 단점을 해결해준다!
string 클래스 사용법
- string은 클래스이지만 마치 기본 타입처럼 사용.
- 예를 들어 '+' 연산자를 사용하여 두 스트링을 합치는(연결) 연산이 가능하다.
- 뿐만 아니라 비교 연산('==', '!=', '<') 도 가능하다. (C처럼 각각의 문자를 []로도 접근 가능)
// 연산자 오버로딩으로 string을 확장해도 메모리 관련 작업을 알아서 처리해줌.
string myString = "hello";
myString += ", there";
string myOtherString = myString;
if (myString == myOtherString) {
myotherString[0] = 'H';
}
cout << myString << endl;
cout << myOtherString << endl;
- 짚고 넘어갈 점
- 스트링을 할당 또는 크기를 조절하는 코드가 흩어져 있어도 메모리 누수 발생이 없다.
- 스트링 객체는 모두 스택 변수로 생성되기 때문.
- 해당 스코프를 벗어나면 소멸자가 모두 정리
- 연산자를 원하는 방식으로 작동할 수 있다.
- "="를 통해서 스트링 복사..
- 스트링을 할당 또는 크기를 조절하는 코드가 흩어져 있어도 메모리 누수 발생이 없다.
- c_str() 메서드를 활용하여 C 와의 호환성을 보장할 수 있다.
- data() 메서드를 사용하면 non-const 스트링에 대해 호출하면 char*를 리턴.
std::string 리터럴
- 소스 코드에 나온 스트링 리터럴은 주로 const char*로 처리함.
- 표준 사용자 정의 리터럴 's'를 사용하려면 using namespace std::string_literals; 또는 using namespace std; 를 추가한다.
// string1의 type은 const char*
auto string1 = "hello";
// string2의 type은 std::string
auto string2 = "world"s;
하이 레벨 숫자 변환
- std namespace는 숫자와 string을 쉽게 변환할 수 있도록 하는 편의(helper) 함수를 제공한다.
- 숫자 타입을 string으로 변환하는 함수들은 메모리 할당 작업도 처리를 해주며 string 객체를 새로 생성하여 리턴한다.
// ex) long double -> string 변환
long doucle d = 3.14L;
string s = to_string(d);
- 반대로 string 타입을 숫자로 변환하는 함수도 std namespace에 정의되어있다.
- str : 원본 string, idx : 변환되지 않은 부분의 맨 앞의 문자 index의 pointer, base : 변환할 수의 밑[기수, 기저]이다.
// stoi 예시
const string to Parse = " 123USD";
size_t = index = 0;
int value = stoi(toParse, &index);
cout << "Parsed value: " << value << endl;
cout << "First non-parsed character: '" << toParse[index] << "'" << endl;
// 실행 결과
// Parsed value: 123
// First non-parsed character: 'U'
로우 레벨 숫자 변환
- C++ 17부터는 로우 레벨 숫자 변환에 대한 함수도 제공
- 헤더에 정의
- 고성능과 로케일 독립성에 튜닝되었다. 따라서 다른 하이 레벨 숫자 변환 함수에 비해서 처리속도가 빠르다.
- 즉, 숫자 데이터와 JSON, XML 등 사이의 변환 작업을 로케일에 독립적이면서 빠른 속도로 처리하기 위해서는 로우 레벨 함수를 사용.
// struct to_chars_result 정의부분
struct to_chars_result {
char* ptr;
errc ec;
};
// 정수를 문자로 변환
to_chars_result to_chars(char* first, char* last, IntegerT value, int base = 10);
std::string out(10, ' ');
auto result = std::to_chars(out.data(), out.data() + out.size(), 12345);
if (result.ec == std::errc()) {
// 제대로 변환된 경우
}
// 위의 예시를 구조적 바인딩을 적용
std::string out(10, ' ');
auto [ptr, ec] = std::to_chars(out.data(), out.data() + out.size(), 12345);
if (ec == std::errc()) {
// 제대로 변환된 경우
}
이상으로 C++의 string 클래스에 대해서 알아보았고,
다음 포스팅에서는 std::string_view 클래스와 2장의 마무리를 하도록 하겠습니다.
감사합니다.
반응형
'🌈 프로그래밍 > C++' 카테고리의 다른 글
[C++] 코딩 스타일에 대하여 (2) | 2021.08.29 |
---|---|
[C++] 동적 스트링 Part 3 (4) | 2021.08.26 |
[C++] 동적 스트링 Part 1 (2) | 2021.08.24 |
[C++] 직원 관리 프로그램 만들기 (2) | 2021.08.23 |
[C++] 유니폼 초기화란? (2) | 2021.08.20 |