[읽기
전에...]
번역된 글에 경어와
비경어가
섞여
있을
수
있사오나
그것은
독자를
무시한
행동이
아니며
역자의
글쓰는
능력이
부족함을
한탄해야
할
것입니다. 허저분한
번역이
보기
싫으시면
바로
출처를
클릭하시기를
바랍니다. 역자의
글이 좋지않아
원문을
보지
않는
愚는
범하지
않도록
합시다
CStdString - 표준 C++ 을
사용한 CString-clone
출처 : https://www.codeproject.com/Articles/1146/CString-clone-Using-Standard-C
2001년 5월 29일
초안
2004년 8월 5일
갱신
2012년 2월 27일
갱신
필자 : Joe O'Leary
역자 : j2doll
'표준 C++ 라이브러리의 basic_string 템플릿에
기반한 CString 의
대체물'
소개
저(필자)는 표준 C++ 라이브러리를
애용해
오면서도, basic_string<>
템플릿
만큼은
좋아하질
않습니다. 때때로
디자이너들의
한물간
방식들이
사용하기
어렵게
만드는
것
같습니다.
반면, 필자는 MFC의
CString
클래스를
사용하기를
즐기는
편이었습니다. CString은 NULL 포인터를
체크해
주고, 암시적으로 const TCHAR* 로
변환시켜
주며, 문자열
프로그램을
사용하기에
손쉬운
멤버
함수들을
제공해
줍니다. ( Format(), Load() 등등 )
하지만
물론, 필자는
더
이상 MFC 를
사용하지는
않습니다. 사실, 플랫폼
이식을
위해서
어떠한
독점적인
라이브러리도
사용하기를
원하지
않기
때문입니다.
그래서
저는
양쪽
세계의
장점만을
모으기로
결심했습니다.
그것이
클래스(사실은
템플릿) basic_string<TCHAR> 에서
상속받은
클래스
CStdString
입니다.
그것은 basic_string
에
CString
전체 API 를
더한
것입니다. 거기에 CString
의
사용
용이성에
basic_string
의
호환성을
보장받게
될
것입니다.
간단히
말해서, CStdString 객체는
다음에
이야기할
몇몇
예외
사항을
제외하고는 basic_string 입니다. 그리고
CString
를
대체할
수도
있는
대체물이기도
합니다.
그것들은 basic_string 과 CString 의
양쪽 API 에서
가장
잘
알려지고
많이
문서화된
부분들입니다.
저는
이
글을
수
년
전, 다른
코드
싸이트에도
올렸었습니다.
하지만
필자가
CodeProject
를
좋아하기에
여기에도
또한
글을
올려봅니다. (이글의
원문은 codeproject에
있습니다.)
필자는
본
클래스를
지난 4년간
상업적인
프로젝트들에도
사용해
왔었습니다.
그
결과, 이
클래스는
필자가
그
동안
만들어
것
중에
가장
유용한
것으로
증명되었습니다.
하지만
물론
다방면으로
디버깅되어야
할
것입니다. 필자는
독자
분들도
그
점을
좋아하시기를
바랍니다. 어떤
문제
점이
있다면
이메일을
보내주시기를
바란다. (필자에게) 도움을
주시면
고맙겠습니다.
CString
함수들의
작동을
나타낸
간단한
어플리케이션
소스를
제공하였습니다. (하지만
정말
대용품입니다.)
예제
프로젝트의
목록들은 CString 과(또는) basic_string 템플릿을
사용합니다.
특징
- 일단 CString
의
대체물로써
잠깐
생각하십시오. (아래
예외
사항도
보시기 바랍니다.)
- 두
개의
항상
사용
가능한
사례 --- wchar_t 기반한
버전
CStdStringW
와 char 기반
버전
CStdStringA. CStdString
는
단지
두
개중
typedef
된
것들의
하나입니다.
- CString
처럼
모든
함수에서
문자열 NULL 체크의
안정성.
- 특정
생성자와
할당
연산자는
자동으로 wchar_t 기반한
문자열과 char 기반한
문자열
간에
변환을
해 줍니다.
- c_str() 으로의
암시적
변환
기능. (C++ 위원회에서는
이런
방식을
권장하지는
않습니다.)
- Windows, UNIX, LINUX
를
포함한
몇몇
플랫폼에서의
빌딩되었다. Dinkumware, GNU, CodeWarrior, STLPort
를
포함해서
표준 C++ 라이브러리에서
구현
작동합니다.
- Win32 Building 은 DCOM IStream 를
사용하는
CStdString
객체의
멤버
함수로써, UNICODE/MBCS 변환
매크로
추가
기능(MFC처럼)을
해
줄
것립니다.
- 기반
클래스
템플릿인
basic_string
의
어떠한
세부
구현도
할
필요가
없습니다.
- 상속받은
템플릿은
basic_string
에
어떠한
멤버
변수와
가상
함수도
더하지
않습니다.
그리고
이
코드에서
지적할
두
가지
주목할
점(CString 과의
호환성과 basic_string 에서의
상속)이
있습니다.
CString 호환성
필자는
완전하게
똑같이
CString API 와
같이
재구현할
수는
없었습니다.
그래서 (공유할
수
있지만
다르게
구현된) CString
와
basic_string
를
위한
두
가지
함수들로
되게
하였습니다.
이러한
경우에
CString
처럼
이라기보다는
basic_string
처럼
행동하는
CStdString
를
만드는
것이
최선이라고
느꼈습니다. (정확하게는…)
- CStdString::operator[]
는 (CString
의 by-reference 와는
다르게) by-value 문자들을
반환합니다.
- 생성자는 (CString
이
선언하는
것의
반대
순서로) 순서별로
문자를
가지고
숫자를 셉니다. 그것은
basic_string<> 의
정렬
방식입니다. 그리고
양쪽
버전
모두의
구현은
불가능할
것입니다.
또한, CString
에서
구현하지
못한
두
개의
함수들이
있습니다. ( LockBuffer()
와
UnlockBuffer() )
basic_string<> 의로부터의
상속
필자가
작성한
basic_string
로부터
상속받은
템플릿은
가상 소멸자(virtual destructor)가
없는
클래스
템플릿입니다.
어떤 C++ 에
관한
소개글들에서는
가상
파괴자가
없는
클래스는
위험하다고
말한적이 있습니다.
때로는
정의되지
않은
것처럼
정의되지
않은
것처럼
해야
할
수도
있습니다.
다음같이
기반
클래스의
포인터를
통해
CStdStringA
를
삭제하는
것처럼
코딩할려면, 기술적으로
정의되지
않은
행동을
해야 합니다.
// 베이스
포인터에
상속
받은
객체를
할당
std::string* pstr = new CStdStringA( "Hi" ) ;
// 베이스
포인터를
통해
파생
삭제
à
정의되지
않음
delete pstr;
|
하지만 (개인적으로) 많이
주목할
점이라고
생각하지는
않습니다.
아마도
문제는
정말
얼마나
자주
문자열
객체를
이처럼
할
것인가
하는냐는
점입니다.
필자는
그
동안
거의
동적으로
문자열
객체를
힙에
할당하는
일은
없었던
것
같습니다.
그리고
베이스
클래스
포인터를
사용하지
않을
것입니다.
이같은
사용하지
않는다면
크게
걱정할
일은
없을
것입니다.
사실
이러한
방식으로
코딩한다면
CStdString
를
사용하는
것에
문제점이
있다고
의심해
볼
만합니다.
적어도 Microsoft Visual C++ 에서
이야기
하자면
에러와
메모리
누수가
없다고
이야기
할
수 있습니다.
아마
많은
다른
컴파일러들이
문제를
준다는
것에도
의심해
보야야
할
것입니다.
하지만
필자의
의심은 C++ 세계의
현실성에
이용하지는
않을
것입니다.
역돌이
外書
: MFC 를
사용하여도
다음같이
문자열을
관리하는
일은
드물
것입니다.
CString *pStr = new
CString () ;
|
(물론 C++ 를
모르시고 Java 만
아시다면
이게
뭐가
문제야
하시겠지만…--;)
역자도
CString
strBuffer = _T( "Buffer" ) ;
_tcscpy( szBuffer, strBuffer );
|
와
같은
방식보다는,
_tcscpy( szBuffer, strBuffer.GetBuffer(strBuffer.GetLength()) );
|
가
더
정상적인
관리라고
생각하며, 필자의
의견에
동의해 봅니다.
이
글은 Verdana 글꼴에
최적화되어
있습니다. 2004년
여름과
가을
사이, 짜증나는
날씨의
어느
날. By j2doll… KIN~
2011년 12월 7일에 source code가 update 되었습니다.
StdString_demo.zip
StdString_src.zip