Skip to content

CStdString:一个跨平台的字符串类实现

引言

A Drop-In replacement for CString that builds on the Standard C++ Library's basic_string template

在C++标准库中有一个std::string字符串类实现,但它的功能简陋一些;而在VC++ MFC中有一个CString类,提供了丰富的字符串操作接口。

CStdString是一个类似CString操作接口的、跨平台的字符串类实现,作者是Joe O'Leary,使用它只需要包含整个头文件StdString.h

相关信息很少,找到下列链接:

早期版本: StdString.h

2011-12-05 的版本(没找到更新版本):

//  FILE:  StdString.h
//  AUTHOR: Joe O'Leary (with outside help noted in comments)
//
//      If you find any bugs in this code, please let me know:
//
//              jmoleary@earthlink.net
//              http://www.joeo.net/stdstring.htm (a bit outdated)
//
//      The latest version of this code should always be available at the
//      following link:
//
//              http://www.joeo.net/code/StdString.zip (Dec 6, 2003)
//
//
//  REMARKS:
//      This header file declares the CStdStr template.  This template derives
//      the Standard C++ Library basic_string<> template and add to it the
//      the following conveniences:
//          - The full MFC CString set of functions (including implicit cast)
//          - writing to/reading from COM IStream interfaces
//          - Functional objects for use in STL algorithms
//
//      From this template, we intstantiate two classes:  CStdStringA and
//      CStdStringW.  The name "CStdString" is just a #define of one of these,
//      based upone the UNICODE macro setting
//
//      This header also declares our own version of the MFC/ATL UNICODE-MBCS
//      conversion macros.  Our version looks exactly like the Microsoft's to
//      facilitate portability.

作者文章(翻译):CString-clone Using Standard C++

介绍

从第一天使用C++标准库起,我就不喜欢它那个基于basic_string<>模板实现的字符串类,总觉得用起来不爽;相反,我却对MFC中的CString类情有独钟,它会检查NULL指针,可以隐式转换为const TCHAR*,以及丰富的操作函数等。但我没法再继续使用MFC,因为我需要移植性。

因此我决定创造一个两全其美的字符串实现,即CStdString。它是一个基于basic_string<TCHAR>模板实现的字符串类,然后在basic_string基础上添加了CString API接口;从而可以获得CString的易用性,又可以获得basic_string的兼容性。

一句话,CStdString可以直接替换掉CString。

特性

  • 可以直接替换CString
  • 同时提供两个实例,基于wchar_t的CStdStringW和基于char的CStdStringA,而CStdString只是其中一个的别名
  • 在所有函数中都可以安全的检查输入的NULL字符串指针
  • 额外的构造函数和赋值操作函数使得可以自动在wchar_t和char字符串之间转换
  • 隐式转换为c_str()
  • 支持多个平台,包括Windows、Unix和Linux;支持多个C++标准库实现,包括Dinkumware、GNU、CodeWarrior和STLPort
  • 不依赖于任何basic_string模板类的实现细节
  • 派生模板类没有在basic_string上添加任何元素和虚函数

CString兼容性

我没有办法完全实现CString的所有API;如果一个函数既有CString版本,又有basic_string版本,但具体实现又不同,这个时候倾向于和basic_string保持一致。

  • CStdString::operator[]返回的字符串是值传递,而CString是以引用传递形式
  • 接收单个字符和字符数量的构造函数,它的顺序是(cout,value),这和CString正好相反
  • 还有两个CString的函数没有实现:LockBuffer和UnlockBuffer

关于性能的说明

"Performance" is a fairly encompassing term. Most of the performance differences will 
come down to the performance of std::string vs CString. That depends upon your 
particular implementation of basic_string, over which I have no control

For the performance of various CString-facade functions (e.g. format), well at this point 
I am long past comparing those or worrying about it. It is not going to make a difference 
in 99% of the cases. You would have to be doing some monster-level of string processing 
for it to matter.

If that sounds like a bit of a dismissal, I suppose it is. This class is mostly meant to 
help people transition over from CString to std::string with a minimum of code-rewrite. 
To help you get off of MFC> The idea is that you can get your code running right away and 
then start refactoring any important string processing code to use basic_string properly, 
in the most efficient way you see fit. This class is not meant to be used alongside CString. 
But if it must, well you can then always use CString instead. This class coexist well with it.

-Joe

别人的言论与评价

mixing-objc-and-c-with-c-template-classes-in-more-than-one-source 上获取到这些信息:

Joe's CStdString is in fact a derived class from std::string.

Anyway, bad thing - good thing: CStdString has no own members. It's a straightforward 
wrapper for one/two byte instantiations of std::basic_string with the convenience of 
most features that MFC CString offers and a wide usability. I used it on Linux more 
than 10 years ago and on Win32 where I couldn't use MFC. Joe's work on it started 1998 
with help of ~50 people within 7 years of development. I think they've managed the 
poorly side effects being in the template.

CStdString如何转换为char*

C++中类型转换例子:

CStdString key = "hello";
char * cKey = const_cast<char *>(key.c_str());

CStdString常用操作接口

  • AppendFormat
  • CompareNoCase
  • Empty
  • Equals
  • Find
  • FindNoCase
  • FindNotInPair
  • Format
  • GetLength
  • MakeLower
  • MakeUpper
  • MakeReverse
  • Match
  • MatchNoCase
  • Replace
  • Trim
  • ......