Click here to Skip to main content
11,495,486 members (67,132 online)
Click here to Skip to main content

CString-clone Using Standard C++

, 7 Dec 2011 CPOL 1.4M 11K 222
Rate this:
Please Sign up or sign in to vote.
A Drop-In replacement for CString that builds on the Standard C++ Library's basic_string template

Introduction

As much as I use and appreciate the Standard C++ Library, I've never liked its string template - basic_string<>. At times, it seems the designers went out of their way to make it difficult to use.

On the other hand, I've always loved the ease of use of MFC's CString class. It checks for NULL pointers, implicitly converts to const TCHAR*, and has some very handy member functions (Format, Load, etc.) that make string programming a breeze. But of course, I don't want to use MFC anymore. In fact, I don't want to rely on any proprietary library because I want portability.

Therefore I decided to combine the best of both worlds and create:

CStdString

This is a class (a template instantiation actually) that derives from from basic_string<TCHAR>. To the basic_string it adds the entire CString API. You get CString ease of use with 100% basic_string compatibility. In short, a CStdString object is a basic_string that (with very few exceptions (noted below) it is also a drop-in replacement for CString. The best part of this is that both APIs (basic_string and CString) are well known and well documented.

I originally submitted this article to another code site (which shall remain nameless Smile | :) ) a few years ago. I like CodeProject so much I thought I'd submit it here too. I have used this class in almost every professional project I've done over the past 4 years. It has proven to be the single most useful piece of code I've ever written. It is also extensively debugged. I hope you like it. If you ever have any problems with it, please e-mail me. I'm happy to help.

I provided a simple source application here to prove some of the CString functions work but it's really just a token. The list of sample projects out there that use CString and/or basic_string is massive.

Features

  • Drop in Replacement for CString (see below for exceptions)
  • Two instantiations available at all times -- wchar_t-based version CStdStringW and char-based version CStdStringA. The name CStdString is just a typedef of one of these two.
  • Safely checks for NULL string pointer inputs (like CString) in all functions
  • Extra constructors and assignment operators to automatically convert between wide (wchar_t-based) and thin (char-based) strings for you.
  • Implicit conversion to c_str(). The C++ committee doesn't like this but I sure do.
  • Builds on several platforms, including Windows, Unix and Linux. Works with several implementations of the Standard C++ Library, including Dinkumware, GNU, CodeWarrior, and STLPort.
  • Win32 builds give you some extra goodies like UNICODE/MBCS conversion macros (just like MFCs) as well as member functions for persisting CStdString objects to and from DCOM IStreams.
  • Makes no use of any implementation details of the base class template (basic_string)
  • The derived template adds no member data to basic_string and adds no virtual functions

There are a couple of issues about this code of that I should point out.

CString Compatibility

I was unable to exactly reproduce the CString API. There are a two functions that both CString and basic_string; share, but implement differently. In these cases, I felt it best to make CStdString behave like basic_string (the base class) rather than CString. To be specific.

  • CStdString::operator[] returns characters by value (unlike CString which returns them by reference)
  • The constructor that takes a character and a count takes them in the order (count, value) which is the opposite of the order CString declares them. That's the order that basic_string<>; needs and it was impossible to implement both versions.

There were also two CString functions I could not implement at all -- LockBuffer and UnlockBuffer.

Deriving From basic_string<>

The template I wrote derives from basic_string, a class template without a virtual destructor. Any introductory text to C++ will tell you that it is dangerous to derive from a class without a virtual destructor. It can lead to behavior that is undefined. So if you were to code the following (deleting a CStdStringA through a pointer to the base class), you would technically get undefined behavior:

// assign DERIVED object to  BASE pointer
std::string* pstr = new CStdStringA("Hi"); 

// delete  DERIVED through BASE class pointer -- UNDEFINED
delete pstr;   

Personally, I don't think this is much of an issue. I mean really how often do you actually do this with string objects? I have rarely (if ever) needed to dynamically allocate a string object on the heap. And if I ever do, I won't using a base-class pointer. So if you don't do this, you'll never have to worry. In fact, even if you do code this way, I doubt you'll have any problems with CStdString. I can tell you that at least with Microsoft Visual C++, even the above code runs just fine with no errors or memory leaks. I doubt many other compilers would give you problems either. However my doubt does not impose reality on the C++ world. Caveat Emptor.

History

  • 7 Dec 2011: Updated source code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Joe O'Leary
Web Developer
United States United States
I've been a software developer since 1990.

While my main page is out of date (and I have therefore blanked it), you can read about the CStdString pages here

http://home.earthlink.net/~jmoleary/stdstring.htm

Comments and Discussions

 
GeneralMy vote of 5 Pin
pasztorpisti24-Aug-13 9:43
memberpasztorpisti24-Aug-13 9:43 
QuestionAbout Stephen Hewitt's GetBuffer Question [modified] Pin
FeiluHang15-Apr-13 2:25
memberFeiluHang15-Apr-13 2:25 
AnswerRe: About Stephen Hewitt's GetBuffer Question Pin
Joe O'Leary17-Apr-13 17:10
memberJoe O'Leary17-Apr-13 17:10 
GeneralMy vote of 5 Pin
Michael Haephrati מיכאל האפרתי8-Jan-13 12:42
mvpMichael Haephrati מיכאל האפרתי8-Jan-13 12:42 
GeneralMy vote of 5 Pin
Dave Calkins15-Nov-12 4:20
memberDave Calkins15-Nov-12 4:20 
SuggestionThank you! Pin
user_user_user12-Nov-12 23:23
memberuser_user_user12-Nov-12 23:23 
Great class. Thank you!
My vote of 5.

Suggestion:
How about using _vscprintf/_vscwprintf function,
when calculating resulting buffer size in CStdStr<T>::FormatV?
I don't know whether compilers other than Visual C++ supports this function,
but Visual C++ supports _vscprintf/_vscwprintf.
Question[My vote of 2] Weak Pin
xComaWhitex11-Oct-12 19:16
memberxComaWhitex11-Oct-12 19:16 
AnswerRe: [My vote of 2] Weak Pin
Joe O'Leary11-Oct-12 19:40
memberJoe O'Leary11-Oct-12 19:40 
GeneralRe: [My vote of 2] Weak Pin
xComaWhitex11-Oct-12 19:45
memberxComaWhitex11-Oct-12 19:45 
GeneralRe: [My vote of 2] Weak Pin
Joe O'Leary11-Oct-12 19:49
memberJoe O'Leary11-Oct-12 19:49 
AnswerRe: [My vote of 2] Weak Pin
Stephen Hewitt11-Oct-12 23:58
memberStephen Hewitt11-Oct-12 23:58 
GeneralRe: [My vote of 2] Weak Pin
xComaWhitex12-Oct-12 0:07
memberxComaWhitex12-Oct-12 0:07 
GeneralRe: [My vote of 2] Weak Pin
Stephen Hewitt12-Oct-12 0:21
memberStephen Hewitt12-Oct-12 0:21 
GeneralRe: [My vote of 2] Weak Pin
xComaWhitex12-Oct-12 0:24
memberxComaWhitex12-Oct-12 0:24 
AnswerRe: [My vote of 2] Weak Pin
Dave Calkins15-Nov-12 4:19
memberDave Calkins15-Nov-12 4:19 
GeneralThis isn't standard C++. [modified] Pin
Stephen Hewitt5-Oct-12 1:51
memberStephen Hewitt5-Oct-12 1:51 
GeneralRe: This isn't standard C++. Pin
Joe O'Leary5-Oct-12 2:12
memberJoe O'Leary5-Oct-12 2:12 
GeneralRe: This isn't standard C++. Pin
Stephen Hewitt5-Oct-12 2:19
memberStephen Hewitt5-Oct-12 2:19 
GeneralRe: This isn't standard C++. Pin
Joe O'Leary5-Oct-12 5:18
memberJoe O'Leary5-Oct-12 5:18 
GeneralRe: This isn't standard C++. Pin
FeiluHang15-Apr-13 2:17
memberFeiluHang15-Apr-13 2:17 
GeneralRe: This isn't standard C++. Pin
Joe O'Leary17-Apr-13 17:08
memberJoe O'Leary17-Apr-13 17:08 
Questionmissing CStringT::Tokenize Pin
Mizan Rahman22-May-12 0:21
memberMizan Rahman22-May-12 0:21 
GeneralMy vote of 5 Pin
Andy Bantly25-Apr-12 6:37
memberAndy Bantly25-Apr-12 6:37 
Questionstd::isspace in VC6 returns true for international characters like Ö [modified] Pin
Karl Edwall4-Mar-12 18:12
memberKarl Edwall4-Mar-12 18:12 
AnswerRe: std::isspace in VC6 returns true for international characters like Ö Pin
Joe O'Leary4-Mar-12 19:20
memberJoe O'Leary4-Mar-12 19:20 
GeneralRe: std::isspace in VC6 returns true for international characters like Ö Pin
Karl Edwall4-Mar-12 19:22
memberKarl Edwall4-Mar-12 19:22 
QuestionBest string code ever - with memory shortage Pin
Bostjan Erzen24-Jan-12 6:14
memberBostjan Erzen24-Jan-12 6:14 
AnswerRe: Best string code ever - with memory shortage Pin
Joe O'Leary24-Jan-12 6:47
memberJoe O'Leary24-Jan-12 6:47 
QuestionNo way to compile it :( Pin
DeepButi27-Dec-11 11:39
memberDeepButi27-Dec-11 11:39 
AnswerRe: No way to compile it :( Pin
Joe O'Leary27-Dec-11 12:26
memberJoe O'Leary27-Dec-11 12:26 
GeneralRe: No way to compile it :( Pin
DeepButi27-Dec-11 22:07
memberDeepButi27-Dec-11 22:07 
GeneralRe: No way to compile it :( Pin
Joe O'Leary28-Dec-11 4:21
memberJoe O'Leary28-Dec-11 4:21 
GeneralRe: No way to compile it :( Pin
DeepButi28-Dec-11 8:23
memberDeepButi28-Dec-11 8:23 
GeneralRe: No way to compile it :( Pin
Joe O'Leary28-Dec-11 4:27
memberJoe O'Leary28-Dec-11 4:27 
GeneralGreat Code Pin
JeffBilkey14-Dec-11 15:41
memberJeffBilkey14-Dec-11 15:41 
GeneralRe: Great Code Pin
Joe O'Leary28-Dec-11 9:02
memberJoe O'Leary28-Dec-11 9:02 
QuestionRe: Great Code Pin
initram14-May-12 8:40
memberinitram14-May-12 8:40 
GeneralMy vote of 5 Pin
Terry Wells12-Dec-11 9:52
memberTerry Wells12-Dec-11 9:52 
QuestionVS2010 unresolved symbols Pin
sisira10-Dec-11 21:05
membersisira10-Dec-11 21:05 
AnswerRe: VS2010 unresolved symbols Pin
Joe O'Leary11-Dec-11 3:52
memberJoe O'Leary11-Dec-11 3:52 
QuestionWhere is the latest code? Pin
sisira10-Dec-11 19:47
membersisira10-Dec-11 19:47 
AnswerRe: Where is the latest code? Pin
Joe O'Leary10-Dec-11 20:54
memberJoe O'Leary10-Dec-11 20:54 
GeneralRe: Where is the latest code? Pin
sisira10-Dec-11 21:01
membersisira10-Dec-11 21:01 
Questiongcc compilation errors Pin
mirko busto9-Dec-11 1:33
membermirko busto9-Dec-11 1:33 
AnswerRe: gcc compilation errors Pin
Joe O'Leary9-Dec-11 4:59
memberJoe O'Leary9-Dec-11 4:59 
Questionfind two a small bug~ Pin
dnybz9-Dec-11 1:17
groupdnybz9-Dec-11 1:17 
AnswerRe: find two a small bug~ Pin
Joe O'Leary9-Dec-11 4:56
memberJoe O'Leary9-Dec-11 4:56 
GeneralRe: find two a small bug~ Pin
dnybz9-Dec-11 5:08
groupdnybz9-Dec-11 5:08 
GeneralRe: find two a small bug~ Pin
Joe O'Leary9-Dec-11 5:37
memberJoe O'Leary9-Dec-11 5:37 
GeneralRe: find two a small bug~ Pin
dnybz9-Dec-11 6:05
groupdnybz9-Dec-11 6:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150520.1 | Last Updated 7 Dec 2011
Article Copyright 2001 by Joe O'Leary
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid