MFC的 CString 学习笔记 -3

原创 2004年02月18日 23:35:00

CString Class Research (3)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

4. CStringData Allocate and dispose.

                In prior section, we know the CStringData has two Parts, One is Header, Include 3 member variables and 1 member function, totally 12 bytes, and the other part is actual data.

                Look the following code in MFC to Allocate and Dispose CStringData and its data buffer.

 

CStringData* pData;

pData = (CStringData*)

                                new BYTE[sizeof(CStringData) + (nLen+1)*sizeof(TCHAR)];

pData->nAllocLength = nLen;

pData->nRefs = 1;

pData->data()[nLen] = '/0';

pData->nDataLength = nLen;

m_pchData = pData->data();

                MFC allocate memory as BYTE array, include CStringData and data buffer, and convert it to CStringData pointer, nLen is the length of string, and one more byte, store a ‘/0’.

                In debug mode, when the nLen <= 64, system allocates 64 bytes, when the nLen <= 128, system allocates 128 bytes....

               

delete[] (BYTE*)pData;

                To dispose buffer, because there are CStringData part (header) and data buffer part, MFC convert the CStringData* to BYTE array, then delete it.

 

5. CString operator =.

                There are two methods to set one CString’s value. If the source string is not a CString object, then MFC will allocate a new buffer to destination CString object, and use memcpy function to copy the content of source string to destination CString.m_pchData.

AllocBeforeWrite(nSrcLen);

memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(TCHAR));

GetData()->nDataLength = nSrcLen;

m_pchData[nSrcLen] = '/0';

               

In addition, if the source string is CString Object, commonly, the destination CString.m_pchData point to source CString.m_pchData. That means, the destination CString.m_pchData and the source CSting.m_pchData will point to the same address, destination CString and the source CString has the same CStringData object.

                When 2 objects share one CStringData, the nRef member variable of CStringData will be set to 2.

If (m_pchData != stringSrc.m_pchData)

{

                if ((GetData()->nRefs < 0 && GetData() != _afxDataNil) ||

                                stringSrc.GetData()->nRefs < 0)

                {

                                // actual copy necessary since one of the strings is locked

                                AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);

                }

                else

                {

                                // can just copy references around

                                Release();

                                ASSERT(stringSrc.GetData() != _afxDataNil);

                                m_pchData = stringSrc.m_pchData;

                                InterlockedIncrement(&GetData()->nRefs);

                }

}

                Two CString share one CStringData will save system memory resource, but there is a risk, that when data in CString object’s CStringData is changed, the other CString object will be changed at the same time, that may be is not we want.

                There is a function in MFC named CopyBeforeWrite to deal with this problem:

void CString::CopyBeforeWrite()

{

                if (GetData()->nRefs > 1)

                {

                                CStringData* pData = GetData();

                                Release();

                                AllocBuffer(pData->nDataLength);

                                memcpy(m_pchData, pData->data(), (pData->nDataLength+1)*sizeof(TCHAR));

                }

                ASSERT(GetData()->nRefs <= 1);

}

                When one CString’s value will be set, MFC will check if there is any other  CString share the same CStringData object with it. If the reference bigger than 1, that means at least 2 CString object reference this CStringData object. The current, will be changed CString must create a new CStringData object to store the new value.

                In the Release() function, if the reference bigger than 1, the buffer will not delete actually.

 

6. LockBuffer() and UnLockBuffer()

                LockBuffer will set nRef member to -1, and UnlockBuffer will set nRef member to 1.

                MSDN said: While in a locked state, the string is protected in two ways:

No other string can get a reference to the data in the locked string, even if that string is assigned to the locked string.

 

The locked string will never reference another string, even if that other string is copied to the locked string.

               

                CString str1, str2;

                str2 = "abcde";

                str2.LockBuffer();

                str1 = str2;

 

                CString str3;

                str3 = "kk";

                str3.LockBuffer();

                str3 = str1;

                The str2’s buffer is locked, when set str1 equal to str2, a new buffer will created to store the str2’s value. str1 and str2 have different CStringData object.

               If the str3’s buffer is not locked, the str3 will share CStringData object with str1, but in this code, str3’s CStringData object is locked, MFC will copy the value of str1 to str3, the str3’s buffer address is not changed.

                Of course , when CString is initializion without init-value, MFC will set a system defined, empty CStringData object to it, the nRef is -1, so LockBuffer() and UnLockBuffer() is no use to system defined, empty CStringData object.

 

关于MFC中CString的用法小结

今天被两个问题折腾了好久,一个是关于结构体数组传递值的问题,就是不知道结构体指针传递形参到子函数后,如何被子函数分解并继续使用,测试过程中老是只能在结构体数组的第一个元素进行操作,后面的操作就会提示“...
  • jackey3Lin
  • jackey3Lin
  • 2015年08月17日 17:19
  • 794

MFC CString用法

MFC CString 用法 读Visual C++ 开发经验技巧宝典第二章—-数据类型 一     Cstring 1.      初始化方法: (1)    直接复...
  • qq61394323
  • qq61394323
  • 2014年05月05日 10:08
  • 1728

MFC  CString 函数用法大全

VC++CString 成员函数用法大全:CString的构造函数CString( );例:CString csStr;CString( const CString& stringSrc );例:CS...
  • lltaoyy
  • lltaoyy
  • 2010年10月12日 17:00
  • 9498

ATL与MFC中的CString

       在ATL和MFC中都可以使用CString类来处理字符串,如果在MFC中要使用ATL中的CString,需要使用名字空间ATL::CString。在书写中,可以使用CStringT,CS...
  • Richard_Sky_Sun
  • Richard_Sky_Sun
  • 2010年08月16日 10:50
  • 2259

在非mfc程序中使用CString类

在非mfc程序中使用CString类       CString在当今软件设计界里还是小有名气的,说它是MFC中使用的最多的类一点也不过,然而在使用sdk编windows程序的时候,确...
  • henry19850318
  • henry19850318
  • 2011年09月28日 09:37
  • 1928

MFC中CString的使用总结

在使用MFC的过程中,不可避免的要使用CString类型对字符串进行处理,特别常用的是CString与char*等类型的转换,现将平时常用的方法整理如下。 1.CString类型的初始化 CStrin...
  • abld99
  • abld99
  • 2016年02月29日 10:44
  • 5211

混用ATL MFC WTL的问题-CString的冲突

主      题: 混用ATL MFC WTL的问题-CString的冲突 作      者: mc_ 回复次数: 3 发表时间: 2010-3-14 12:42:33 正文内容: ...
  • xelone
  • xelone
  • 2011年09月09日 13:56
  • 2535

MFC中CString和int的转换

int转换为CString: CString csName; int num; csName.Format("%d", num); CString转换为int: CString csName; i...
  • u011848617
  • u011848617
  • 2014年08月25日 19:24
  • 2484

MFC_CString TCHAR的互相转换

CString->TCHAR*的转化可以用函数GetBuff() 函数原型为:LPTSTR GetBuffer( int nMinBufLength ); CString str("CStri...
  • u010003835
  • u010003835
  • 2015年08月27日 11:18
  • 1769

MFC总结(17) --- CString 参数传递问题

标题:MFC中关于CString 参数传递 作者:厚道心得 原文章地址:http://blog.sina.com.cn/s/blog_3f59eb3d010008a8.html   当定义类...
  • oBuYiSeng
  • oBuYiSeng
  • 2015年11月19日 15:43
  • 1118
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC的 CString 学习笔记 -3
举报原因:
原因补充:

(最多只允许输入30个字)