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")));