love in C++, live on MFC

to get ready...

C++博客 首页 新随笔 联系 聚合 管理
  47 Posts :: 0 Stories :: 97 Comments :: 0 Trackbacks
关于GetBuffer/ReleaseBuffer,网上比较流行的一种说法是:如果你要直接修改CString的内部数据,就要调用GetBuffer/ReleaseBuffer.我也同意这样的表述.

下面是几个例子,主要是错误的例子,来加深理解.
1
CString strTest = "123";
char* p = strTest.GetBuffer(0
);
int i =
 atoi(p);
strTest.ReleaseBuffer();
这种用法当然没有错,但是我认为这里的GetBuffer/ReleaseBuffer是没有必要的,为什么呢?因为
int __cdecl atoi(const char *) 的参数是const char*,CString的内部数据肯定不会被修改的.
所以上面的代码可以直接写成
CString strTest = "123";
int i = atoi((LPCTSTR)strTest);
顺便说一下GetBuffer的参数问题,网上的例子中,很多都是GetBuffer(5) GetBuffer(10)这样的常数,实际中的程序不可能是这么容易事先知道的,所以也就有了strTest.GetBuffer(strTest.GetLength() )的写法.其实,GetBuffer(0)就可以了.可以由GetBuffer的源码得到验证.

2
    CString strTest = "123 45";

    
//some other code

    CString strTest2 = strTest;
    
char seps[] = " "
;
    
char* pToken = 0
;
    
//char* pStr = strTest2.GetBuffer(0);

    pToken = strtok((char*)(LPCTSTR)strTest2, seps);
    //pToken = strtok(pStr, seps);
    
while
(pToken)
        pToken 
=
 strtok(NULL, seps);
         //strTest2.ReleaseBuffer(0);
运行上面的代码,可以看到strTest的值也变了,呵呵,这就是程序中一些关与CString的奇怪问题的起源.如果用注释中的GetBuffer/ReleaseBuffer方法,就一点问题也没有了.
同样,对于ReleaseBuffer的参数,缺省的是-1,但是我不建议.因为-1表示使用当前的00结束符位置来确定新的长度.而上面的例子中,strtok是会重新设置00结束符的,所以,安全的做法,就是把这个CString的长度设为0,ReleaseBuffer(0),反正它的内容已经变了,也没有人要用了.
说明一下,GetBuffer/ReleaseBuffer方法只能保证strTest不变,strTest2还是会变的.所以,对于一个成员变量,比如m_strTest2调用ReleaseBuffer要多一个心眼,局部变量就不用想这么多了.
那么怎么从最开始就意识到程序写错了呢?上面代码中(char*)(LPCTSTR)是很危险的,把const去掉了,否则strtok是编译不过的,也从一个侧面说明了const的重要性.
posted on 2006-03-21 17:51 flyingxu 阅读(9821) 评论(6)  编辑 收藏 引用 所属分类: VC/MFC

Feedback

# re: CString的另一个问题,关于GetBuffer/ReleaseBuffer的几个错误例子 2006-03-21 20:37 恋花蝶
写得很不错.  回复  更多评论
  

# re: CString的另一个问题,关于GetBuffer/ReleaseBuffer的几个错误例子 2006-03-22 09:21 沐枫
……这两个问题总得是刚从C转到C++的人容易犯的。
由于习惯了C的思维,而又不认真查阅文档,想当然耳,所犯的错误。

特别是第2个问题,不至于要这么用吧,为什么要绕几个弯呢?
CString str( "123 45" );
CString resToken;

int curPos= 0;
while (curPos != -1)
{
resToken= str.Tokenize(" ", curPos);
cout << (LPCTSTR)resToken << endl;
};

用Tokenize,不会改变源字串。  回复  更多评论
  

# re: CString的另一个问题,关于GetBuffer/ReleaseBuffer的几个错误例子 2006-03-23 12:12 flyingxu
@沐枫
我也一直很奇怪CString为什么没有封装好的token函数,你说得Tokenize,我也是第一次听说。
看了一下,发现VC6的CString是没有Tokenize这个函数的,VC7的MFC中的CString才有。  回复  更多评论
  

# re: CString的另一个问题,关于GetBuffer/ReleaseBuffer的几个错误例子 2006-03-23 17:08 沐枫
那vc6的 atlstring 有没有?我没装vc6不好意思。  回复  更多评论
  

# re: CString的另一个问题,关于GetBuffer/ReleaseBuffer的几个错误例子 2006-04-06 11:38 chen
CString的Bug还是挺多的,特别是在UNICODE下
  回复  更多评论
  

# re: CString的另一个问题,关于GetBuffer/ReleaseBuffer的几个错误例子 2006-04-06 12:04 flyingxu
@chen
能举个例子吗?很多人多说CString不好或者怎样,我觉得到底是哪里不好,应该搞清楚,这样才心里更有底  回复  更多评论
  


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理