CString? 如果你接触过vc/mfc,呵呵,这个名字你一定见过。那么你就大胆的看下面的一个例子吧
----------------------------------
一段简单的代码如下:
----------------------------------
void C...Dlg::OnOK()
{
CString str;
strcpy((LPSTR)(LPCTSTR)str,"Hello!");
AfxMessageBox(str);
CString strL = "";
int n;
n = strL.GetLength();
AfxMessageBox(strL);
CDialog::OnOK();
}
说明:用(LPSTR)(LPCTSTR)这种怪怪的方法其实是故意的,目的是为了模仿现实问题。
现实是strcpy函数的调用在dll中做的,因为调用dll中函数没有参数类型检查,因此不用这种显式转换,而在这里没有办法,只是为了模仿strcpy的调用。
----------------------------------
大家可以跟踪看一看:
首先str得到Hello!没有问题
奇怪在下面,定义了第二个CString类型的对象,并赋初值为空字符,但跟踪观察发现,strL中同样也是Hello!指针地址是一样的,但是奇怪的是GetLength()却是0。既然长度为0,但却有值,而且还可以正常使用,比如用AfxMessageBox显示。但是如果我赋值不是空字符而是一个具体的,则没有问题。
上面的问题其实很简单,但我第一次遇到时却百思不得其解。所以现在回想着写下这段文字,目的是针对那些还没有注意CString结构的程序员们,至于高手们,呵呵,希望可以指点我一二,不甚感激!
解决上述问题前,先解释一个名词写入复制技术(CopyBeforeWrite):当使用一个CString对象a来初始化另一个CString对象b时,为了节省空间,新对象b并不分配空间,它所要做的只是将自己的指针指向对象a的那块内存空间,只有当需要修改对象a或者b中的字符串时,才会为新对象b申请内存空间。这种技术其实就是微软为了提高效率想出的一个怪招,既然有,我们就了解一下。
接下来,就分析一下CString的结构了:
CString大致可以理解成下面结构
| | |
| Header | Data |
| | |
也就是说CString其实包括一个header(数据头)和data(数据区)
CString是对于原来标准c中字符串类型的一种的包装。因为,通过很长时间的编程,我们发现,很多程序的bug多和字符串有关,典型的有:缓冲溢出、内存泄漏等。而且这些bug都是致命的,会造成系统的瘫痪。因此c++里就专门的做了一个类用来维护字符串指针。标准c++里的字符串类是string,在microsoft MFC类库中使用的是CString类。通过字符串类,可以大大的避免c中的关于字符