Użycie nieprzetworzonego ciągu
Tak, czasami naprawdę możesz to zrobić. Używając const char *, tablic char alokowanych na stosie i literałów łańcuchowych możesz to zrobić w taki sposób, że nie ma w ogóle alokacji pamięci.
Pisanie takiego kodu często wymaga więcej przemyślenia i staranności niż użycie łańcucha lub wektora, ale przy użyciu odpowiednich technik można to zrobić. Dzięki odpowiednim technikom kod może być bezpieczny, ale zawsze musisz się upewnić, że kopiując do char [] albo masz jakieś gwarancje co do długości kopiowanego ciągu, albo z wdziękiem sprawdzasz i obsługujesz zbyt duże łańcuchy. Nie robienie tego sprawiło, że ta rodzina funkcji strcpy zyskała reputację niebezpiecznej.
Jak szablony mogą pomóc w pisaniu bezpiecznych buforów znaków
Jeśli chodzi o bezpieczeństwo buforów char [], pomocne mogą być szablony, ponieważ mogą one tworzyć enkapsulację do obsługi rozmiaru bufora za Ciebie. Szablony takie jak ten są wdrażane np. Przez firmę Microsoft w celu zapewnienia bezpiecznych zamienników strcpy. Poniższy przykład pochodzi z mojego własnego kodu, prawdziwy kod ma znacznie więcej metod, ale to powinno wystarczyć, aby przekazać podstawową ideę:
template <int Size>
class BString
{
char _data[Size];
public:
BString()
{
_data[0]=0;
_data[Size-1]=0;
}
const BString &operator = (const char *src)
{
strncpy(_data,src,Size-1);
return *this;
}
operator const char *() const {return _data;}
};
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
return dst = src;
}
char *
prawie nie ma narzutów. Dokładniestd::string
nie wiem, co ma narzut , prawdopodobnie zależy to od implementacji. Prawie nie oczekuję, że narzut będzie znacznie większy niż w przypadku gołego wskaźnika char. Ponieważ nie posiadam kopii standardu, nie mogę tak naprawdę szczegółowo określić żadnych gwarancji udzielonych przez standard. Wszelkie różnice w wydajności prawdopodobnie będą się różnić w zależności od wykonywanych operacji.std::string::size
może przechowywać rozmiar obok danych znakowych i dzięki temu być szybszym niżstrlen
.append(const string&)
Iappend(const char*, size_t)
zamiastoperator+=()
.