⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tstring.tex

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 TEX
字号:
\section{wxString overview}\label{wxstringoverview}Classes: \helpref{wxString}{wxstring}, \helpref{wxArrayString}{wxarraystring}, \helpref{wxStringTokenizer}{wxstringtokenizer}\subsection{Introduction}\label{introductiontowxstring}wxString is a class which represents a character string of arbitrary length (limited by {\it MAX\_INT} which is usually 2147483647 on 32 bit machines) and containingarbitrary characters. The ASCII NUL character is allowed, but be aware thatin the current string implementation some methods might not work correctlyin this case.wxString works with both ASCII (traditional, 7 or 8 bit, characters) as well asUnicode (wide characters) strings.This class has all the standard operations you can expect to find in a string class:dynamic memory management (string extends to accommodate new characters),construction from other strings, C strings and characters, assignment operators,access to individual characters, string concatenation and comparison, substringextraction, case conversion, trimming and padding (with spaces), searching andreplacing and both C-like \helpref{Printf()}{wxstringprintf} and stream-likeinsertion functions as well as much more - see \helpref{wxString}{wxstring} for a list of all functions.\subsection{Comparison of wxString to other string classes}\label{otherstringclasses}The advantages of using a special string class instead of working directly withC strings are so obvious that there is a huge number of such classes available.The most important advantage is the need to alwaysremember to allocate/free memory for C strings; working with fixed size buffers almostinevitably leads to buffer overflows. At last, C++ has a standard string class(std::string). So why the need for wxString?There are several advantages:\begin{enumerate}\itemsep=0pt\item {\bf Efficiency} This class was made to be as efficient as possible: bothin terms of size (each wxString objects takes exactly the same space as a {\itchar *} pointer, sing \helpref{reference counting}{wxstringrefcount}) and speed.It also provides performance \helpref{statistics gathering code}{wxstringtuning} which may be enabled to fine tune the memory allocation strategy for yourparticular application - and the gain might be quite big.\item {\bf Compatibility} This class tries to combine almost full compatibilitywith the old wxWidgets 1.xx wxString class, some reminiscence to MFC CStringclass and 90\% of the functionality of std::string class.\item {\bf Rich set of functions} Some of the functions present in wxString arevery useful but don't exist in most of other string classes: for example, \helpref{AfterFirst}{wxstringafterfirst}, \helpref{BeforeLast}{wxstringbeforelast}, \helpref{operator<<}{wxstringoperatorout} or \helpref{Printf}{wxstringprintf}. Of course, all the standard stringoperations are supported as well.\item {\bf Unicode} wxString is Unicode friendly: it allows to easily convertto and from ANSI and Unicode strings in any build mode (see the \helpref{Unicode overview}{unicode} for more details) and maps to either{\tt string} or {\tt wstring} transparently depending on the current mode.\item {\bf Used by wxWidgets} And, of course, this class is used everywhereinside wxWidgets so there is no performance loss which would result fromconversions of objects of any other string class (including std::string) towxString internally by wxWidgets.\end{enumerate}However, there are several problems as well. The most important one is probablythat there are often several functions to do exactly the same thing: forexample, to get the length of the string either one of length(), \helpref{Len()}{wxstringlen} or \helpref{Length()}{wxstringlength} may be used. The first function, as almostall the other functions in lowercase, is std::string compatible. The second oneis "native" wxString version and the last one is wxWidgets 1.xx way. So thequestion is: which one is better to use? And the answer is that:{\bf The usage of std::string compatible functions is strongly advised!} It willboth make your code more familiar to other C++ programmers (who are supposed tohave knowledge of std::string but not of wxString), let you reuse the same codein both wxWidgets and other programs (by just typedefing wxString as std::stringwhen used outside wxWidgets) and by staying compatible with future versions ofwxWidgets which will probably start using std::string sooner or later too.In the situations where there is no corresponding std::string function, pleasetry to use the new wxString methods and not the old wxWidgets 1.xx variantswhich are deprecated and may disappear in future versions.\subsection{Some advice about using wxString}\label{wxstringadvices}Probably the main trap with using this class is the implicit conversion operator to {\it const char *}. It is advised that you use \helpref{c\_str()}{wxstringcstr}instead to clearly indicate when the conversion is done. Specifically, thedanger of this implicit conversion may be seen in the following code fragment:\begin{verbatim}// this function converts the input string to uppercase, output it to the screen// and returns the resultconst char *SayHELLO(const wxString& input){    wxString output = input.Upper();    printf("Hello, %s!\n", output);    return output;}\end{verbatim}There are two nasty bugs in these three lines. First of them is in the call to the {\it printf()} function. Although the implicit conversion to C strings is appliedautomatically by the compiler in the case of\begin{verbatim}    puts(output);\end{verbatim}because the argument of {\it puts()} is known to be of the type {\it const char *},this is {\bf not} done for {\it printf()} which is a function with variablenumber of arguments (and whose arguments are of unknown types). So this call maydo anything at all (including displaying the correct string on screen), althoughthe most likely result is a program crash. The solution is to use \helpref{c\_str()}{wxstringcstr}: just replace this line with\begin{verbatim}    printf("Hello, %s!\n", output.c_str());\end{verbatim}The second bug is that returning {\it output} doesn't work. The implicit cast isused again, so the code compiles, but as it returns a pointer to a bufferbelonging to a local variable which is deleted as soon as the function exits,its contents is totally arbitrary. The solution to this problem is also easy:just make the function return wxString instead of a C string.This leads us to the following general advice: all functions taking stringarguments should take {\it const wxString\&} (this makes assignment to thestrings inside the function faster because of \helpref{reference counting}{wxstringrefcount}) and all functions returningstrings should return {\it wxString} - this makes it safe to return localvariables.\subsection{Other string related functions and classes}\label{relatedtostring}As most programs use character strings, the standard C library provides quitea few functions to work with them. Unfortunately, some of them have rathercounter-intuitive behaviour (like strncpy() which doesn't always terminate theresulting string with a NULL) and are in general not very safe (passing NULLto them will probably lead to program crash). Moreover, some very usefulfunctions are not standard at all. This is why in addition to all wxStringfunctions, there are also a few global string functions which try to correctthese problems: \helpref{wxIsEmpty()}{wxisempty} verifies whether the stringis empty (returning {\tt true} for {\tt NULL} pointers), \helpref{wxStrlen()}{wxstrlen} also handles NULLs correctly and returns 0 forthem and \helpref{wxStricmp()}{wxstricmp} is just a platform-independentversion of case-insensitive string comparison function known either asstricmp() or strcasecmp() on different platforms.The {\tt <wx/string.h>} header also defines \helpref{wxSnprintf}{wxsnprintf} and \helpref{wxVsnprintf}{wxvsnprintf} functions which should be used insteadof the inherently dangerous standard {\tt sprintf()} and which use {\ttsnprintf()} instead which does buffer size checks whenever possible. Ofcourse, you may also use \helpref{wxString::Printf}{wxstringprintf} which isalso safe.There is another class which might be useful when working with wxString: \helpref{wxStringTokenizer}{wxstringtokenizer}. It is helpful when a string mustbe broken into tokens and replaces the standard C library {\itstrtok()} function.And the very last string-related class is \helpref{wxArrayString}{wxarraystring}: itis just a version of the "template" dynamic array class which is specialized to workwith strings. Please note that this class is specially optimized (using itsknowledge of the internal structure of wxString) for storing strings and so it isvastly better from a performance point of view than a wxObjectArray of wxStrings.\subsection{Reference counting and why you shouldn't care about it}\label{wxstringrefcount}All considerations for wxObject-derived \helpref{reference counted}{trefcount} objectsare valid also for wxString, even if it does not derive from wxObject.Probably the unique case when you might want to think about referencecounting is when a string character is taken from a string which is not aconstant (or a constant reference). In this case, due to C++ rules, the"read-only" {\it operator[]} (which is the same as \helpref{GetChar()}{wxstringgetchar}) cannot be chosen and the "read/write" {\it operator[]} (the same as \helpref{GetWritableChar()}{wxstringgetwritablechar}) is used instead. As thecall to this operator may modify the string, its data is unshared (COW is done)and so if the string was really shared there is some performance loss (both interms of speed and memory consumption). In the rare cases when this may beimportant, you might prefer using \helpref{GetChar()}{wxstringgetchar} insteadof the array subscript operator for this reasons. Please note that \helpref{at()}{wxstringat} method has the same problem as the subscript operator inthis situation and so using it is not really better. Also note that if allstring arguments to your functions are passed as {\it const wxString\&} (see thesection \helpref{Some advice}{wxstringadvices}) this situation will almostnever arise because for constant references the correct operator is called automatically.\subsection{Tuning wxString for your application}\label{wxstringtuning}\normalbox{{\bf Note:} this section is strictly about performance issues and isabsolutely not necessary to read for using wxString class. Please skip it unlessyou feel familiar with profilers and relative tools. If you do read it, pleasealso read the preceding section about \helpref{reference counting}{wxstringrefcount}.}For the performance reasons wxString doesn't allocate exactly the amount ofmemory needed for each string. Instead, it adds a small amount of space to eachallocated block which allows it to not reallocate memory (a relativelyexpensive operation) too often as when, for example, a string is constructed bysubsequently adding one character at a time to it, as for example in:\begin{verbatim}// delete all vowels from the stringwxString DeleteAllVowels(const wxString& original){    wxString result;    size_t len = original.length();    for ( size_t n = 0; n < len; n++ )    {        if ( strchr("aeuio", tolower(original[n])) == NULL )            result += original[n];    }    return result;}\end{verbatim}This is quite a common situation and not allocating extra memory at all wouldlead to very bad performance in this case because there would be as many memory(re)allocations as there are consonants in the original string. Allocating toomuch extra memory would help to improve the speed in this situation, but due toa great number of wxString objects typically used in a program would alsoincrease the memory consumption too much.The very best solution in precisely this case would be to use \helpref{Alloc()}{wxstringalloc} function to preallocate, for example, len bytesfrom the beginning - this will lead to exactly one memory allocation beingperformed (because the result is at most as long as the original string).However, using Alloc() is tedious and so wxString tries to do its best. Thedefault algorithm assumes that memory allocation is done in granularity of atleast 16 bytes (which is the case on almost all of wide-spread platforms) and sonothing is lost if the amount of memory to allocate is rounded up to the nextmultiple of 16. Like this, no memory is lost and 15 iterations from 16 in theexample above won't allocate memory but use the already allocated pool.The default approach is quite conservative. Allocating more memory may bringimportant performance benefits for programs using (relatively) few very longstrings. The amount of memory allocated is configured by the setting of {\itEXTRA\_ALLOC} in the file string.cpp during compilation (be sure to understandwhy its default value is what it is before modifying it!). You may try settingit to greater amount (say twice nLen) or to 0 (to see performance degradationwhich will follow) and analyse the impact of it on your program. If you do it,you will probably find it helpful to also define WXSTRING\_STATISTICS symbolwhich tells the wxString class to collect performance statistics and to showthem on stderr on program termination. This will show you the average length ofstrings your program manipulates, their average initial length and also thepercent of times when memory wasn't reallocated when string concatenation wasdone but the already preallocated memory was used (this value should be about98\% for the default allocation policy, if it is less than 90\% you shouldreally consider fine tuning wxString for your application).It goes without saying that a profiler should be used to measure the precisedifference the change to EXTRA\_ALLOC makes to your program.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -