char* vs std :: c ++의 문자열 [폐쇄
문제
언제 사용해야합니까? std::string
그리고 언제 사용해야합니다 char*
배열을 관리합니다 char
C ++에서 s?
사용해야하는 것 같습니다 char*
성능 (속도)이 중요하고 메모리 관리로 인해 위험한 비즈니스를 기꺼이 받아들이려고합니다.
고려해야 할 다른 시나리오가 있습니까?
해결책
복사를 피하기 위해 크거나 인스턴스에 대한 포인터가 크면 std :: strings를 참조하여 전달할 수 있으므로 Char Pointers를 사용하여 실제 이점이 없습니다.
실제 텍스트 인 모든 것에 대해 std :: string/wstring을 사용합니다. char *
다른 유형의 데이터에 유용하며, 그렇게 할 수있는 것처럼 거래 될 수 있습니다. 그렇지 않으면 std :: 벡터가 갈 길입니다.
이 모든 것에는 예외가있을 수 있습니다.
다른 팁
내 관점은 다음과 같습니다.
- "C"코드를 호출하지 않으면 char *를 사용하지 마십시오.
- 항상 std :: string을 사용하십시오 : 더 쉽고, 더 친숙하고, 최적화되어 있으며, 표준이며, 버그가 없어지고, 점검하고 작동하는 것으로 입증되었습니다.
원시 문자열 사용
예, 때때로 당신은 정말로 이것을 할 수 있습니다. const char *를 사용할 때, char 배열은 스택 및 문자열 리터럴에 할당 된 방식으로 할당 할 수 있습니다.
이러한 코드를 작성하려면 문자열이나 벡터를 사용하는 것보다 종종 더 많은 사고와 관리가 필요하지만 적절한 기술로 수행 할 수 있습니다. 적절한 기술을 사용하면 코드가 안전 할 수 있지만, char []로 복사 할 때는 항상 복사중인 문자열의 렌트에 약간의 보장이 있거나 대형 문자열을 우아하게 확인하고 처리해야합니다. 그렇게하지 않는 것은 Strcpy 기능의 가족에게 안전하지 않다는 명성을 준 것입니다.
템플릿이 안전한 숯 버퍼를 작성하는 데 도움이되는 방법
char [] 버퍼 안전의 경우, 템플릿은 버퍼 크기를 처리하기위한 캡슐화를 만들 수 있으므로 도움이 될 수 있습니다. 이와 같은 템플릿은 Microsoft에 의해 구현되어 strcpy에 대한 안전한 교체를 제공합니다. 여기서 예제는 내 자신의 코드에서 추출되며 실제 코드에는 더 많은 방법이 있지만 기본 아이디어를 전달하기에 충분해야합니다.
template <int Size>
class BString
{
char _data[Size];
public:
BString()
{
_data[0]=0;
// note: last character will always stay zero
// if not, overflow occurred
// all constructors should contain last element initialization
// so that it can be verified during destruction
_data[Size-1]=0;
}
const BString &operator = (const char *src)
{
strncpy(_data,src,Size-1);
return *this;
}
operator const char *() const {return _data;}
};
//! overloads that make conversion of C code easier
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
return dst = src;
}
사용해야 할 경우 char*
그리고 아닙니다 std::string
정적 문자열 상수가 필요할 때입니다. 그 이유는 주문 모듈에 대한 컨트롤이 정적 변수를 초기화하고 다른 모듈의 다른 글로벌 개체가 초기화되기 전에 문자열을 참조 할 수 있기 때문입니다. http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#static_and_global_variables
std::string
장점 :
- 당신을 위해 메모리를 관리합니다 (문자열은 성장할 수 있으며 구현은 더 큰 버퍼를 할당합니다).
- 고급 프로그래밍 인터페이스는 나머지 STL과 잘 작동합니다.
std::string
단점 : - 두 개의 별개의 STL 문자열 인스턴스는 동일한 기본 버퍼를 공유 할 수 없습니다. 따라서 가치를 통과하면 항상 새 사본을받습니다. - 성과 페널티가 있지만 요구 사항이 특별하지 않으면 무시할 수 없다고 말하고 싶습니다.
사용하려면 고려해야합니다 char*
다음의 경우 :
- 이 배열은 매개 변수로 전달됩니다.
- 배열의 최대 크기를 미리 알고 있습니다 (알고 있거나 부과).
- 이 배열에서 아무런 변환도하지 않습니다.
실제로 C ++에서 char*
옵션, 파일 이름 등으로 고정 된 작은 단어에 종종 사용됩니다 ...
c ++ std :: string을 사용하는시기 :
- 문자열은 전반적으로 숯*보다 안전합니다. 일반적으로 숯으로 일을 할 때* 일이 올바른지 확인해야합니다. 문자열 클래스에서는이 모든 것이 당신을 위해 이루어집니다.
- 일반적으로 char*를 사용할 때는 할당 된 메모리를 제거해야합니다. 파괴 될 때 내부 버퍼를 제거하기 때문에 문자열로 수행 할 필요가 없습니다.
- 문자열은 C ++ stringstream과 잘 작동하며, 형식화 된 IO는 매우 쉽습니다.
char*를 사용할 때
- char*를 사용하면 장면 뒤에서 일어나는 일을 더 많이 제어 할 수 있습니다. 즉, 필요한 경우 성능을 조정할 수 있습니다.
라이브러리를 작성하는 경우 (const) char*를 매개 변수로 사용하십시오. STD :: 문자열 구현은 컴파일러마다 다릅니다.
C 라이브러리를 사용하려면 C- 스트링을 처리해야합니다. API를 C에 노출하려는 경우에도 동일하게 적용됩니다.
std :: 문자열에서 대부분의 작업을 기대할 수 있습니다 (예 : 예 : find
) 가능한 한 최적화되므로 최소한 순수한 C 대응 물뿐만 아니라 수행 할 가능성이 높습니다.
또한 std :: 문자열 반복자는 종종 기본 숯 배열에 포인터에 매핑됩니다. 따라서 반복자 위에 고안하는 모든 알고리즘은 성능 측면에서 Char * 위의 동일한 알고리즘과 본질적으로 동일합니다.
조심해야 할 것은 예를 들어입니다 operator[]
- 대부분의 STL 구현은 한계 검사를 수행하지 않으며,이를 기본 문자 배열에서 동일한 작업으로 변환해야합니다. Afaik Stlport는 선택적으로 경계 점검을 수행 할 수 있으며,이 시점 에서이 연산자는 약간 느리게됩니다.
그렇다면 std :: 문자열을 사용하면 무엇이 당신을 얻습니까? 수동 메모리 관리로부터 당신을 방해합니다. 배열 크기 조정이 쉬워지고 일반적으로 메모리 해방에 대해 덜 생각해야합니다.
문자열 크기를 조정할 때 성능이 걱정된다면 reserve
유용 할 수있는 기능.
텍스트 등의 숯 배열을 사용하는 경우 std :: 문자열을보다 유연하고 사용하기 쉽습니다. 데이터 스토리지와 같은 다른 용도로 사용하는 경우? 배열 사용 (선호 벡터)
성능이 중요하더라도 더 잘 사용합니다 vector<char>
- 사전에 메모리 할당을 허용하고 메모리 누출을 피하는 데 도움이됩니다. Vector :: Operator []를 사용하면 오버 헤드로 연결되지만 항상 버퍼의 주소를 추출하여 Char*인 경우와 같이 정확하게 색인 할 수 있습니다.
내부적으로 대부분의 std :: 문자열 구현 사본을 쓰기에, 참조 카운트 시맨틱을 참조하여 문자열을 참조하지 않더라도 참조 계산 시맨틱.