鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 手机系统开发 > J2ME > >

今天发现CString的一个问题

来源:互联网 作者:佚名 时间:2015-09-25 05:44
昨天经理跟我说 发现 一个 问题 ,有个树里面的叶子的显示有 问题 ,本来应该是这样的: 网块1 --网元1 --网元2 网块2 --网元1 --网元2 但是现在却变成这样了: 网块2 --网元1 --网元2 网块2 --网元1 --网元2 而以前一直都是好的,这是怎么回事呢? 从版本控

昨天经理跟我说发现一个问题,有个树里面的叶子的显示有问题,本来应该是这样的:

网块1

--网元1

--网元2

网块2 

--网元1

--网元2

但是现在却变成这样了:

网块2

--网元1

--网元2

网块2 

--网元1

--网元2

而以前一直都是好的,这是怎么回事呢?

从版本控制器里面看到这个部分的代码在4月份的时候有过一次修改。

 for (int i=0;i<arPartID.GetSize();i++)
 {
  char bfPart[40];
  int j=arPartID.GetAt(i);
  int iErrorCode =oEngine.ORGetPartData(j,"%partname",bfPart);
  CStringArray* pArray=new CStringArray();
  pArray->Add(bfPart);
......

  s_data.Add(pArray);
 }

现在的代码是:

 for (int i=0;i<arPartID.GetSize();i++)                                                        1
 {                                                                                                                      2
  CString strPartName;                                                                               3
  int j=arPartID.GetAt(i);                                                                               4
  int iErrorCode =oEngine.ORGetPartName(j,strPartName);             5
  CStringArray* pArray=new CStringArray();                                            6
  pArray->Add(strPartName);                                                                     7
 ......

  s_data.Add(pArray);
 }

当时改动的目的是这个适配器函数oEngine::ORGetPartName的接口变了,所以想着要变CString就一起变吧。找到是由于这个变化引起的问题后,我写了一个Trace的函数,跟踪s_data的变化。一行行的看,最后终于发现问题了!

这个循环执行第一遍的时候没什么异常,第二遍执行到第5行后,s_data里面的“网块1”,突然变成了“网块2”。

研究一阵子才发现,原来CString在使用无参数的构造函数时:

CString::CString()
{
 Init();
}

_AFX_INLINE void CString::Init()
 { m_pchData = afxEmptyString.m_pchData; }

#define afxEmptyString ((CString&)*(CString*)&_afxPchNil)

// afxChNil is left for backward compatibility

AFX_DATADEF TCHAR afxChNil = '/0';

现在就很清楚了,当使用使用无参数的构造函数时,CString是将自己m_pchData统一指向MFC定义的一个指针afxChNil 的,而像我那样在构造函数之后马上将CString当成字符串指针使用,其结果是我修改了MFC内部定义的afxChNil 的值。然后,我再构造另一个无参数CString时,它立刻就被赋值成前一个值了。如果我还照旧在构造函数之后马上将CString当成字符串指针使用,其结果是我得到了两个值一样的CString。

不知道我说明白了没有,简单一点的测试代码可能是这样的:

const CString A="A";           1
 const CString B="B";          2
 CString str1;                        3
 strcpy(str1,A);                      4
 CString str2;                        5
 strcpy(str2,B);                     6

预期效果是执行到第六行,str1也变成了"B"。不过这点代码无法执行,因为strcpy不支持将CString转化成char *。这就需要你自己写一个类似的拷贝函数,我使用的那个oEngine::ORGetPartName里面就调了一个这样的函数:int GetPartData( int PartID, const char *formatstring,... );

这样的函数现在好像不是很常用了,因为不进行严格的参数检查很容易出错。

好吧,就算是我的拷贝函数用错了,但是微软怎么就不能把它那个该死的afxChNil定义成常量呢。那我不是马上就知道有问题了吗,唉,以前总是听别人说CString不好用,但没有体验过,今天我算是领教了!

 

 

网友评论
<