CString Argument Passing

This article explains how to pass CString objects to functions and how to return CString objects from functions.

CString Argument-Passing Conventions

When you define a class interface, you must determine the argument-passing convention for your member functions. There are some standard rules for passing and returning CString objects. If you follow the rules described in Strings as Function Inputs and Strings as Function Outputs, you'll have efficient, correct code.

Strings as Function Inputs

The most efficient and secure way to use a CString object in called functions is to pass a CString object to the function. Despite the name, a CString object doesn't store a string internally as a C-style string that has a NULL terminator. Instead, a CString object keeps careful track of the number of characters it has. Having CString provide an LPCTSTR pointer to a NULL-terminated string is a small amount of work that can become significant if your code has to do it constantly. The result is temporary because any change to the CString contents invalidates old copies of the LPCTSTR pointer.

It does make sense in some cases to provide a C-style string. For example, there can be a situation where a called function is written in C and doesn't support objects. In this case, coerce the CString parameter to LPCTSTR, and the function will get a C-style NULL-terminated string. You can also go the other direction and create a CString object by using the CString constructor that accepts a C-style string parameter.

If the string contents are to be changed by a function, declare the parameter as a nonconstant CString reference (CString&).

Strings as Function Outputs

Typically you can return CString objects from functions because CString objects follow value semantics like primitive types. To return a read-only string, use a constant CString reference (const CString&). The following example illustrates the use of CString parameters and return types:

class CName : public CObject
{
private:
   CString m_firstName;
   TCHAR m_middleInit;
   CString m_lastName;
public:
   CName() {}
   void SetData(LPCTSTR fn, const TCHAR mi, LPCTSTR ln)
   {
      m_firstName = fn;
      m_middleInit = mi;
      m_lastName = ln;
   }
   void GetData(CString& cfn, TCHAR& mi, CString& cln)
   {
      cfn = m_firstName;
      mi = m_middleInit;
      cln = m_lastName;
   }
   CString GetLastName()
   {
      return m_lastName;
   }
};

 

CName name;
CString last, first;
TCHAR middle;
name.SetData(_T("John"), 'Q', _T("Public"));
ASSERT(name.GetLastName() == _T("Public"));
name.GetData(first, middle, last);
ASSERT((first == _T("John")) && (last == _T("Public")));

See also

Strings (ATL/MFC)