August 2nd Thursday (八月 二日 木曜日)

本文探讨了wxString类在wxWidgets库中的使用方法及注意事项,特别是如何避免隐式转换带来的潜在错误,并提供了安全返回字符串的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Probably the main trap with using this class is the implicit conversion operator
to const char *.  It is advised that you use c_str() instead to clearly indicate
when the conversion is done.  Specifically, the danger of this implicit conversion
may be seen in the following code fragment:

// this function converts the input string to uppercase, output it to the screen
// and returns the result
const char *SayHELLO(const wxString& input)
{
    wxString output = input.Upper();

    printf("Hello, %s!/n", output);

    return output;
}

There are two nasty bugs in these three lines. First of them is in the call to
the printf() function.  Although the implicit conversion to C strings is applied
automatically by the compiler in the case of

puts(output);

because the argument of puts() is known to be of the type const char *, this is
not done for printf() which is a function with variable number of arguments (and
whose arguments are of unknown types).  So this call may do anything at all (including
displaying the correct string on screen), although the most likely result is a program
crash.  The solution is to use c_str(): just replace this line with

printf("Hello, %s!/n", output.c_str());

  The second bug is that returning output doesn't work. The implicit cast is used again,
so the code compiles, but as it returns a pointer to a buffer belonging 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 string arguments should
take const wxString& (this makes assignment to the strings inside the function faster because
of reference counting) and all functions returning strings should return wxString - this makes
it safe to return local variables.

  And finally, the standard preprocessor tokens enumerated above expand to ANSI strings but
it is more likely that Unicode strings are wanted in the Unicode build.  wxWidgets provides
the macros __TFILE__, __TDATE__ and __TTIME__ which behave exactly as the standard ones except
that they produce ANSI strings in ANSI build and Unicode ones in the Unicode build.

  To summarize, here is a brief example of how a program which can be compiled in both ANSI
and Unicode modes could look like:

#ifdef __UNICODE__
    wchar_t wch = L'*';
    const wchar_t *ws = L"Hello, world!";
    int len = wcslen(ws);

    wprintf(L"Compiled at %s/n", __TDATE__);
#else // ANSI
    char ch = '*';
    const char *s = "Hello, world!";
    int len = strlen(s);

    printf("Compiled at %s/n", __DATE__);
#endif // Unicode/ANSI

  Of course, it would be nearly impossibly to write such programs if it had to be done this way.

  In wxWidgets, the code fragment from above should be written instead:

wxChar ch = wxT('*');
wxString s = wxT("Hello, world!");
int len = s.Len();

  We have a wxChar type which maps either on char or wchar_t depending on the mode in which
program is being compiled.  There is no need for a separate type for strings though, because
the standard wxString supports Unicode, i.e. it stores either ANSI or Unicode strings depending
on the compile mode.

  Finally, there is a special wxT() macro which should enclose all literal strings in the program.
As it is easy to see comparing the last fragment with the one above, this macro expands to nothing
in the (usual) ANSI mode and prefixes 'L' to its argument in the Unicode mode.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值