16. String 클래스와 표준 템플릿 라이브러리 (미완, 일반화 프로그래밍)

2023. 9. 18. 19:04·C++/C++

string 클래스

문자열 생성

string 클래스 입력

문자열 작업

string 클래스가 제공하는 그 밖의 기능

C++ 시스템들은 실제 문자열보다 훨씬 큰 메모리 블록을 대입하여 문자열이 자랄 수 있는 공간을 제공한다. 그러고 나서, 그 문자열이 마침내 그 크기를 초과하게 되면, 프로그램은 그 크기의 두 배인 새로운 블록을 대입하여 연속적인 크기 조절 없이 문자열이 자랄 수 있게 더 많은 공간을 제공한다. capacity() 메서드는 현재 블록의 크기를 리턴하고, reserve() 메서드는 그 블록을 위한 최소 크기를 사용자가 요청하게 한다.

 

string 객체를 가지고 있지만 C 스타일 문자열이 필요할 때

c_str() 메서드가, 호출하는 string 객체와 동일한 내용을 가지는 C 스타일 문자열을 가리키는 포인터를 리턴한다는 것이다.

open() 메서드가 C 스타일 문자열 매개변수를 요구하기 때문에 아래와 같이 사용할 수 있다.

string filename;
ofstream fout;
fout.open(filename.c_str());

string 다양성

이 클래스에는 다음과 같은 네 가지 typedef이 들어 있다.

  • typedef basic_string<char> string;
  • typedef basic_string<wchar_t> wstring;
  • typedef basic_string<char16_t> u16string;
  • typedef basic_string<char32_t> u32string;

이는 char뿐만 아니라, wchar_t형, wchar16_t형, wchar32_t 형에 기초하는 문자열도 사용할 수 있게 허용한다. 

 

스마트 포인터 템플릿 클래스

smart pointer는 포인터처럼 행동하는 클래스 객체이지만, 몇 가지 추가 기능을 지닌다. 여기서 우리는 동적 메모리 대입을 관리하기 위한 스마트 포인터 템플릿에 대해 알아본다.

스마트 포인터의 사용

3개의 스마트 템플릿(auto_ptr, unique_ptr, shared_ptr)은 각각 new를 통해 (직접 또는 간접적으로) 얻어지는 주소를 대입할 포인터를 정의한다. 스마트 포인터가 수명을 다했을 떄, 파괴자는 delete를 사용하여 메모리를 헤제한다. 

이러한 스마트 포인터 객체들 중 하나를 생성하기 위해서는 템플릿을 정의하는 memory 헤더 파일을 소스 코드에 포함시켜야 한다.

아래는 코드 예시이다.

auto_ptr<double> pd(new double);
unique_ptr<double> pd(new double);
shared_ptr<double> pd(new double);

스마트 포인터는 std 이름 공간에 속하는 것을 주의해야 한다.

 

unique_ptr

하나의 스마트 포인터만이 특정 객체를 소유할 수 있도록 소유권 개념을 도입한다.

그 객체를 소유하고 있는 경우에만, 파괴자가 그 객체를 삭제한다.

 

shared_ptr

하나의 특정한 객체를 참조하는 스마트 포인터들이 몇 개인지 추적하는 똑똑한 스마트 포인터를 생성한다.

이것을 참조 카운팅(reference counting)이라 한다. 대입할 때마다 참조 카운팅이 1씩 증가된다. 어떤 스마트 포인터의 수명이 다할 때마다 참조 카운팅이 1씩 감소된다. 따라서 마지막 스마틔 포인터의 수명이 다했을 떄 delete가 호출된다.

auto_ptr보다 unique_ptr이 더 좋은 이유

auto_ptr은 대입과 동시에 원본의 소유권이 없어지기에 파괴자의 중복을 막을 순 있지만, 원본이 더 이상 유효한 값을 가지고 있지 않는 것이 큰 문제이다.

unique_ptr을 사용하게되면, 대입시 컴파일러가 허락을 하지 않으므로 더 안전하다. \

(오른쪽에 rvalue가 있어야 성립된다.)

(컴파일 에러와 프로그램 크래시의 차이)

문제는 대입연산시(하나의 스마트 포인터에서 다른 스마트 포인터로 대입하는 과정)에 타이밍이 맞지 않는 경우가 있다. 이럴때를 위해 정의해줄 함수가 있다.

unique_ptr<string> demo(const char *s)
{
	unique_ptr<string> temp(new string(s));
	return temp;
}

unique_ptr<string> ps;
ps = demo("Uniquely special");

함수는 임시 객체(rvalue)를 반환하기 때문에 유효하지 않은 값에 접근할 가능성이 없어진다.

move()를 통해 rvalue를 만들어도 사용이 가능하다.

 

또한, uniqye_ptr은 array로 사용될 수 있다는 장점을 가진다. 그렇기에 delete와 new, delete[] 와 new[]가 쌍으로 사용되어야 한다는것을 기억하고 있어야 한다.

auto_ptr과 shared_ptr은  delete, new 는 사용할 수 있지만, delete[], new[] 는 사용할 수 없다.

 

스마트 포인터 선택

하나의 객체에 대해 하나 이상의 포인터를 사용한다면, shqred_ptr

프로그램이 같은 객체를 가리키기 위해 다중 포인터를 필요로 하지 않는다면, unique_ptr

 

표준 템플릿 라이브러리

표준 템플릿 라이브러리는 컨테이너(container), 이터레이터(iterator), 함수 객체(function object), 알고리즘(algorithm)을 나타내는 템플릿들의 집합을 제공한다.

컨테이너는 배열과 같이, 여러 개의 값을 저장할 수 있는 구성 단위이다. 이터레이터는 배열안에서 포인터를 사용하여 위치를 옮기듯이, 컨테이너 안에서 위치를 옮길수 있도록 도와 주는 객체들이다.

함수 객체는 클래스 객체일 수도 있고, 함수 포인터일 수도 있다(함수 이름은 포인터의 역할을 하기 때문에 함수 이름도 여기에 포함된다).

알고리즘은 STL을 사용하여 배열, 큐, 리스트와 같은 다양한 컨테이너들을 생성할 수 있다. 또한 STL은 검색, 정렬, 무작위화(randomize) 등 다양한 작업을 수행할 수 있게 해준다.

즉, STL은 일반화 프로그래밍이다.

 

vector 템플릿 클래스


allocator 복습

 

String 클래스와 마찬가지로, 여러 가지 STL 컨테이너 템플릿들이 메모리 관리에 사용할 allocator객체를 지정하는 선택적 템플릿 매개변수를 사용한다. 예를 들어, vector 텀플릿은 아래와 같이 시작한다.

template<class T, class Allocator = allocator<T> >
	class vector{...

이 템플릿 매개변수를 위한 값을 생략하면,  컨테이너 템플릿은 allocator<T> 클래스를 디폴트로 사용한다. 이 클래스는 new와 delete를 표준 방식으로 사용한다.


vector에서 할 수 있는 것

vector의 double형 특수화를 위한 이터레이터 선언

vector<double>::iterator pd;	// pd는 이터레이터

그러면 다음과 같은 코드를 사용하는 이터레이터 pd를 사용할 수 있다.

vector<double> scores;
pd = scores.begin();	// pd가 첫 번째 원소를 지시하게 만든다.
*pd = 22.3;				// pd를 내용 참조하여 첫 번째 원소에 값을 대입한다.
++pd;					// pd가 그 다음 원소를 지시하게 만든다.

보다시피 이터레이터는 포인터처럼 행동한다. 그 밖에도 C++11의 자동 타입 추론을 유용하게 활용할 수 있는 경우도 있다.

vector<double>::iterator pd = scores.begin();
// 대신 다음과 같이 사용할 수 있다.
auto pd = scores.begin();

범위 [it1,it2)는 두 이터레이터 it1과 it2에 의해 정의된다. it1으로부터 시작하여 it2 바로 앞까지 의미한다. 즉 it1은 포함하지만 it2는 포함하지 않는다.


erase()

scores.erase(scores.begin(), scores.begin() + 3);

insert()

// scores.begin() 즉 0위치에 scores.begin() + 3 부터 scores.end() 까지를 삽입한다.
scores.insert(scores.begin(), scores.begin() + 3, scores.end() );

 

vector에서 할 수 있는 그 밖의 것

대표적인 STL 함수 for_each(), random_shuffle(), sort()

for_each()

for_each() 함수는 지시된 함수를 그 범위 안에 있는 각 컨테이너 원소에 적용한다.

지시된 함수는 컨테이너 원소들의 값을 변경하면 안된다.

for_each() 함수는 모든 컨테이너 클래스에 사용할 수 있다.

for_each(books.begin(), books.end(), ShowReview);

random_shuffle()

random_shuffle() 함수는 범위를 지정하는 두 개의 이터레이터를 사용하여 그 범위 안에 있는 원소들을 무작위 순서고 재배치한다.

임의 접근을 허용한다.

random_shuffle(books.begin(), books.end());

sort()

sort() 는 두가지 버전이 있는데,

첫 번째 버전은 범위를 지정하는 두 개의 이터레이터를 사용한다. 그것은 컨테이너에 저장되어 있는 데이터형의 원소에 맞게 정의된 < 연산자를 사용하여 그 범위를 정렬한다. 따라서 컨테이너의 원소들이 사용자 정의 객체일 때는 데이터형에 맞게 정의된 operator<() 함수가 있어야 한다.

3번 째 매개변수로 greater<>()을 사용하면 내림차순으로 정렬된다. (연산의 기준이 3번쨰 매개변수 이다.)

임의 접근을 허용한다.

sort(books.begin(), books.end());				// default = 내림차순
sort(books.begin(), books.end(), greater<>());	// 오름차순

 


전체 순서화(total ordering)

a < b 와 a > b 가 둘 다 false이면 a와 b는 동일한 것이다. 

 

순약 순서화(strict weak ordering)

사용자 정의 자료형 멤버중 같은 측면이 하나밖에 없을 수도 있다.

따라서 순약 순서화를 말할 때에는 두 객체가 동일하다(identical)라고 말하는 것보다 동등하다(equivalent)고 말하는 것이 바람직하다.


Range에 기초한 루프

range에 기초한 루프는 STL과 함께 작동하도록 설계되어 있다.

for(auto & x : books) InflateReview(x);

일반화 프로그래밍

일반화 프로그래밍의 목적은 데이터형과 무관한 코드를 작성하는 것이다. 

STL은 일반화 프로그래밍의 한 예이다. 알고리즘에 중점을 두고, 데이터의 추상화와 재활용이 가능한 코드의 작성을 추구한다.

이터레이터가 필요한 이유

이터레이너틑 알고리즘을, 사용할 컨테이너형과 무관하게 만든다. 이터레이터는 STL의 일반화 접근에 필수 구성 요소이다.

 

이터레이터의 종류

이터레이터 계층

개념, 개량, 모델

컨테이너의 종류

결합 컨테이너

순서가 부여되지 않은 결합

컨테이너

 

함수 객체(Functor)

펑크터 개념

미리 정의된 펑크터

어댑터블 펑크터와 함수 어댑터

 

알고리즘

알고리즘 그룹

알고리즘의 일반적인 특성

STL과 string 클래스

함수와 컨테이너 메서드

STL 사용하기

 

기타 라이브러리

vector와 valarray, 그리고 array

initializer_list 템플릿

initializer_list 사용

프로그램 분석

'C++ > C++' 카테고리의 다른 글

14장 C++ 코드의 재활용 (미완성)  (1) 2023.10.04
13. 클래스의 상속  (0) 2023.09.14
[C++] Rule of three  (0) 2023.08.27
Overloading  (0) 2023.07.28
12. 클래스와 동적 메모리 대입, +추가 필요  (0) 2023.07.25
'C++/C++' 카테고리의 다른 글
  • 14장 C++ 코드의 재활용 (미완성)
  • 13. 클래스의 상속
  • [C++] Rule of three
  • Overloading
메카인
메카인
  • 메카인
    메카인의 지식창고
    메카인
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 코딩 공부
        • TIL(Today I Learn)
        • TIL
        • 백준(C++)
        • Python
        • 알고리즘
        • 프로젝트 회고
      • C++
        • C++
        • C++ STL
        • C,C++ mCoding yotube
      • 게임개발
        • 언데드서바이벌_골드메탈_클론코딩
        • 3D_골드메탈_클론코딩
        • 유니티_문제해결
        • 게임 수학
      • Unreal 공부
        • UE5 GameDev
        • Unreal Engine 4 C++ The Ult..
      • 교재 문제 풀이
        • 운영체제
      • 정보처리기사
        • 정처기 요약
        • 정처기 오답노트
      • 학교수업
        • 데이터베이스
        • 프로그래밍 언어론
        • 리눅스 시스템
        • 네트워크
      • 일상
        • 주식
        • 독서
      • (비공개 전용)
        • memory
        • Build
        • OOP
        • Smart Pointer
        • lamda
        • 게임 수학
        • 모던 C++
        • 모던 C++ STL
        • 모던 C++ Concurrency, Paralle..
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • 블로그 관리
  • 링크

  • 공지사항

    • 공지사항 - 인생과 블로그의 목표
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
메카인
16. String 클래스와 표준 템플릿 라이브러리 (미완, 일반화 프로그래밍)
상단으로

티스토리툴바