bar_1

contents_map

2008年4月14日月曜日

CString (MFC)

CString (MFC)


A common lament seen in various newsgroups deals with the Standard string class as opposed to the Microsoft Foundation Class called CString. Often programmers realize that a standard portable answer is better than a proprietary nonportable one, but in porting their application from a Win32 platform, they discover that they are relying on special functions offered by the CString class.
いろんなニュース・グループで、同じような慷慨が見られる。Microsoft Foundation Class のCStringのかわりに、標準文字列クラスをつかったときの話題だ。 プログラマはよく、プロプラエタリ・ノンポータブルな解よりもスタンダード・ポータブルな解のほうがよいものとする。 しかし、アプリケーションをWin32プラットフォームからポーティングするにあたって、 CStringクラスの特殊な関数を使ってしまっていることに気づくのだ。

Things are not as bad as they seem. In this message, Joe Buck points out a few very important things:
このことは彼らが思っているほど悪くない。 このメッセージ では、Joe Buck がいくつか重要なことを明らかにしている:

  • The Standard string supports all the operations that CString does, with three exceptions.
    標準 string は、3つの例外を除いてCStringのすべての操作をサポートしている。

  • Two of those exceptions (whitespace trimming and case conversion) are trivial to implement. In fact, we do so on this page.
    ��つの例外のうち2つ(ホワイト・スペースのトリミングとケース・コンバージョン)は、造作もなく実装できる。実際、このページでも扱っている。
  • The third is CString::Format, which allows formatting in the style of sprintf. This deserves some mention:
    ��つめは CString::Format で、これはsprintf タイプのフォーマットを可能にする。これはいくつか注意を要する:

The old libg++ library had a function called form(), which did much the same thing. But for a Standard solution, you should use the stringstream classes. These are the bridge between the iostream hierarchy and the string class, and they operate with regular streams seamlessly because they inherit from the iostream hierarchy. An quick example:
古い libg++ ライブラリは、form()とよばれる関数を持っていた。これは同じことをするものだった。しかし現在の標準の解としては、stringstreamクラスを使えばいい。これらはiostream階層とstringクラスのブリッジであり、通常のstreamをシームレスに操作する。なぜならstringstreamは、iostreamクラス階層から継承されているからである。単純な例:

#include <iostream>
#include <string>
#include <sstream>

string f (string& incoming) // incoming は "foo N"
{
istringstream incoming_stream(incoming);
string the_word;
int the_number;

incoming_stream >> the_word // "foo" を抽出
>> the_number; // "N" を抽出

ostringstream output_stream;
output_stream << "The word was " << the_word
<< " and 3*N was " << (3*the_number);

return output_stream.str();
}

A serious problem with CString is a design bug in its memory allocation. Specifically, quoting from that same message:
CStringの深刻な問題は、メモリ・アロケーションの設計バグである。正確には、同メッセージから引用する:

CString suffers from a common programming error that results in
poor performance. Consider the following code:
CString は、プアなパフォーマンスとなる一般的なプログラミング・エラー
の影響をうける。以下のコード例をかんがえよう:


CString n_copies_of (const CString& foo, unsigned n)
{
CString tmp;
for (unsigned i = 0; i < n; i++)
tmp += foo;
return tmp;
}

This function is O(n^2), not O(n). The reason is that each +=
causes a reallocation and copy of the existing string. Microsoft
applications are full of this kind of thing (quadratic performance
on tasks that can be done in linear time) -- on the other hand,
we should be thankful, as it's created such a big market for high-end
ix86 hardware. :-)
この関数は O(n^2)であって、O(n)ではない。理由は、ループ中毎回+=演算子が
メモリの再アロケーションと既存の文字列のコピーをおこなうからだ。Microsoftの
アプリケーションはこの類の問題に満ちている(線形時間で解ける問題が
��乗オーダの性能)--ただ一方でこれは感謝すべきなんだ。ハイ・エンドのix86
ハードウェアの巨大市場を創出しているんだからね(笑)。

If you replace CString with string in the above function, the
performance is O(n).
上記関数で CString を string に置き換えれば、パフォーマンスは O(n) だ。


Joe Buck also pointed out some other things to keep in mind when comparing CString and the Standard string class:
Joe Buck はまた、 CString と 標準stringクラスを比較するにあたり、他にもいくつか気に止めておくべきことを明らかにしている。

  • CString permits access to its internal representation; coders who exploited that may have problems moving to string.
    CString は内部表現へのアクセスを許している;それを利用するコーダーは、string に変換するときに問題となるかもしれない。
  • Microsoft ships the source to CString (in the files MFC\SRC\Str{core,ex}.cpp), so you could fix the allocation bug and rebuild your MFC libraries. Note: It looks like the CString shipped with VC++6.0 has fixed this, although it may in fact have been one of the VC++ SPs that did it.
    Microsoft は CString のソース・コードを配布している(ファイルはMFC\SRC\Str{core,ex}.cpp)。だから自前でアロケーション・バグを修正し、リビルドすることができる。 注意: VC++6.0のCStringは、バグが修正されているように見える。サービス・パックでかもしれないが。
  • string operations like this have O(n) complexity if the implementors do it correctly. The libstdc++ implementors did it correctly. Other vendors might not.
    このような string のメソッドは、O(n) の複雑度を持つ。 実装者が正しくやれば。 libstdc++ の実装者は、これを正しく実装している。他のベンダは、そうでないかもしれない。

  • While parts of the SGI STL are used in libstdc++, their string class is not. The SGI string is essentially vector<char> and does not do any reference counting like libstdc++'s does. (It is O(n), though.) So if you're thinking about SGI's string or rope classes, you're now looking at four possibilities: CString, the libstdc++ string, the SGI string, and the SGI rope, and this is all before any allocator or traits customizations! (More choices than you can shake a stick at -- want fries with that?)
    SGI STLの複数の部分は libstdc++ に使われているが、stringクラスはそうではない。 SGI stringは本質的に vector<char> であり、かつ一切リファレンス・カウントをしていない。libstdc++ はしているが。(O(n)だけれども )。だからもしSGIのstring かまたは ropeクラスを考えているのなら、4つの選択肢がある:CString, libstdc++, SGI string, SGI rope である。そしてこれは一切、アロケータ、トレーツのカスタム化以前である!
    (いろいろ取り揃えてございます。ご一緒にポテトもいかがですか?)

Prev Up Next
縮めてフィット Home パート VI. ローカライゼーション


0 件のコメント:

コメントを投稿

何かありましたら、どうぞ: