모두의 코드
C++ 레퍼런스 - string 생성자
string::string
basic_string 의 경우 여러가지 형태의 생성자를 지원하고 있습니다. 특히 생성자를 잘 이용하면 코드를 더 깔끔하게 쓸 수 도 있기 때문에 상당히 유용합니다.
또한, 생성자 종류가 매우 많지만, 그 큰 틀은 다 비슷하기 때문에 (생성자 뿐만이 아니라 C++ STL 라이브러리의 모든 함수들이 비슷한 형태를 취하고 있습니다.) 크게 어려움 없이 숙지하실 수 있습니다.
참고로 직접 할당자를 만들어서 사용하지 않는 이상 Allocator
가 무엇 인지는 크게 고민하지 않으셔도 됩니다. 대부분의 경우 디폴트 할당자를 사용할 것입니다.
생성자 오버로딩 종류
basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) {} explicit basic_string(const Allocator& alloc) noexcept;
빈 문자열을 생성한다.
basic_string(size_type count, CharT ch, const Allocator& alloc = Allocator());
count 만큼의 문자 ch
를 가진 문자열을 생상한다. 같은 문자가 반복되는 문자열을 생성할 때 사용하면 편리하다.
basic_string(const basic_string& other, size_type pos, const Allocator& alloc = Allocator()); basic_string(const basic_string& other, size_type pos, size_type count, const Allocator& alloc = Allocator());
인자로 전달된 문자열 other
의 부분문자열로 문자를 생성한다. 첫 번째 경우, other
의 pos
부터 끝까지를 문자열로 생성하고, 두 번째의 경우 pos
부터 count 만큼을 택해서 문자열을 생성한다. substr 함수의 작동 원리와 동일하다.
basic_string(const CharT* s, size_type count, const Allocator& alloc = Allocator());
s 의 첫 count 문자만큼을 취해서 문자열을 생성한다. 만약에 s 가 가리키는 문자열의 길이가 count 보다 작다면 어떤식으로 작동해야 할지 정의되어 있지 않다. 따라서 반드시 s 의 길이가 count 이상 인지 확인해야 한다.
basic_string(const CharT* s, const Allocator& alloc = Allocator());
널 종류 문자열 s 를 복사해서 문자열을 생성한다.
template <class InputIt> basic_string(InputIt first, InputIt last, const Allocator& alloc = Allocator());
first
부터 last
바로 전 까지의 문자들을 취해서 문자열을 생성한다.
basic_string(const basic_string& other); basic_string(const basic_string& other, const Allocator& alloc); basic_string(basic_string&& other) noexcept; basic_string(basic_string&& other, const Allocator& alloc);
basic_string 의 복사 생성자와 이동 생성자들.
basic_string(std::initializer_list<CharT> ilist, const Allocator& alloc = Allocator());
초기화자 리스트(initializer list) ilist
로 부터 문자열을 생성한다.
template <class T> explicit basic_string(const T& t, const Allocator& alloc = Allocator());
t
를 string_view sv
로 변환 한 뒤에 (std::basic_string_view<CharT, Traits> sv = t
),
sv
로 부터 문자열을 초기화 한다 (이는 basic_string(sv.data(), sv.size(), alloc)
와 동일함). 따라서 T
는 반드시 string_view 로 변환 가능한 타입이어야만 한다.
basic_string(const T& t, size_type pos, size_type n, const Allocator& alloc = Allocator());
t
를 string_view sv
로 변환한 뒤에 (std::basic_string_view<CharT, Traits> sv = t
), pos
부터 n
개의 문자들로 문자열을 초기화 한다 (basic_string(sv.substr(pos, n), a)
와 동일). 이 경우 역시 T
가 string_view 로 변환 가능한 타입이어야 한다.
인자들
alloc
- 문자열의 할당을 담당하는 할당자. 명시하지 않을 경우 디폴트 할당자가 사용된다.count - 만들어지는 문자열의 길이
ch
- 초기화 시에 어떤 문자를 사용할 것인지.pos
- 사용할 첫 번째 문자의 위치first, last
- 읽어들일 문자의 범위 (last
는 읽어들이지 않는다.)s
- 문자열 초기화를 위해 읽어들일 문자 배열을 가리키는 포인터other
- 문자열 초기화를 위해 읽어들일 다른 문자열ilist
- 초기화자 리스트(std::initializer_list
)t
- std::basic_string_view 로 변환 가능한 객체로, 이를 바탕으로 문자열을 초기화 한다.
복잡도
이동 생성자를 제외한 나머지 모두의 경우, 생성되는 문자열의 길이에 비례한다. 즉 $O(n)$, $n$ 은 문자열의 길이
주의 할 점
'\0' (널 문자열) 를 포함하고 있는 문자열로 초기화 할 시에, 주의해야 할 점이 있다.
std::string s1 = "ab\0\0cd"; // s1 contains "ab" std::string s2{"ab\0\0cd", 6}; // s2 contains "ab\0\0cd"
위 s1
의 경우, basic_string( const CharT* s, const Allocator& alloc = Allocator())
꼴의 생성자가 오버로딩 되서, 뒤에 오는 \0cd
를 무시하게 된다. (첫 번째 NULL 문자를 만날 때 까지 만 읽기 때문에).
반면에 s2
의 경우, basic_string( const CharT* s, size_type count, const Allocator& alloc = Allocator());
꼴의 생성자가 오버로딩 되서, NULL
을 만나느냐의 유무와 상관없이 정해진 길의 문자열 (위 경우 6) 을 읽기 때문에 s1
과 같은 문제는 생기지 않는다.
s1
과 같은 문제를 막기 위해서는 리터럴 연산자인 operator""s
를 사용해서, 문자열을 있는 그대로 읽을 수 있게 된다.
std::string s3 = "ab\0\0cd"s; // s3 contains "ab\0\0cd"
#include <cassert> #include <cctype> #include <iostream> #include <iterator> #include <string> int main() { { // string::string() std::string s; assert(s.empty() && (s.length() == 0) && (s.size() == 0)); } { // string::string(size_type count, charT ch) std::string s(4, '='); std::cout << s << '\n'; // "====" } { std::string const other("Exemplary"); // string::string(string const& other, size_type pos, size_type count) std::string s(other, 0, other.length() - 1); std::cout << s << '\n'; // "Exemplar" } { // string::string(charT const* s, size_type count) std::string s("C-style string", 7); std::cout << s << '\n'; // "C-style" } { // string::string(charT const* s) std::string s("C-style\0string"); std::cout << s << '\n'; // C 스타일 문자열 (널 종료 문자열) } { char mutable_c_str[] = "another C-style string"; // string::string(InputIt first, InputIt last) std::string s(std::begin(mutable_c_str) + 8, std::end(mutable_c_str) - 1); std::cout << s << '\n'; // C 스타일 문자열 (널 종료 문자열) } { std::string const other("Exemplar"); std::string s(other); std::cout << s << '\n'; // "Exemplar" } { // string::string(string&& str) std::string s(std::string("C++ by ") + std::string("example")); std::cout << s << '\n'; // "C++ by example" } { // string(std::initializer_list<charT> ilist) std::string s({'C', '-', 's', 't', 'y', 'l', 'e'}); std::cout << s << '\n'; // "C-style" } { // 재미 있게도, 아래 함수는 string(InputIt first, InputIt last) 버전으로 // 오버로딩 된다 (InputIt 가 int 인 것으로). 하지만, 이 경우 이 오버로딩 // 꼴은 마치 string(size_type count, charT ch) 가 호출된 것 같이 작동한다. std::string s(3, std::toupper('a')); std::cout << s << '\n'; // "AAA" } }
실행 결과
실행 결과
==== Exemplar C-style C-style C-style string Exemplar C++ by example C-style AAA
참고 자료
assign - 문자열에 문자를 대입한다.
operator=
- 문자열의 문자열을 대입한다.
댓글을 불러오는 중입니다..