WEB开发网
开发学院软件开发VC 深入分析MFC中的CArray类 阅读

深入分析MFC中的CArray类

 2007-03-16 21:56:31 来源:WEB开发网   
核心提示: template<class TYPE, class ARG_TYPE>AFX_INLINE TYPE CArray<TYPE, ARG_TYPE>::operator[](int nIndex) const{ return GetAt(nIndex); }temp
template<class TYPE, class ARG_TYPE>
AFX_INLINE TYPE CArray<TYPE, ARG_TYPE>::operator[](int nIndex) const
  { return GetAt(nIndex); }
template<class TYPE, class ARG_TYPE>
AFX_INLINE TYPE& CArray<TYPE, ARG_TYPE>::operator[](int nIndex)
  { return ElementAt(nIndex); }
前一种情况是返回的对象的实例,后一种情况是返回对象的引用。分别调用不同的成员函数来实现。我们来比较一下这两个函数的实现(省略部分):TYPE  GetAt(int nIndex) const
  { ASSERT(nIndex >= 0 && nIndex < m_nSize);
    return m_pData[nIndex]; }
TYPE& ElementAt(int nIndex)
  { ASSERT(nIndex >= 0 && nIndex < m_nSize);
    return m_pData[nIndex]; }
除了返回值不同,其它都一样,有什么区别吗?我们来看一个实例说明。CArray<int,int&> arrInt;
arrInt.SetSize(10);
int n = arrInt.GetAt(0);
int& l = arrInt.ElementAt(0);
cout << arrInt[0] <<endl;
n = 10;
cout << arrInt[0] <<endl;
l = 20;
count << arrInt[0] << endl;
结果会发现,n的变化不会影响到数组,而l的变化会改变数组元素的值。实际即是对C++中引用运算符的运用。
CArray下标访问是非安全的,它并没有超标预警功能。虽然使用ASSERT提示,但下标超范围时没有进行处理,会引起非法内存访问的错误。
前面谈到模板实例化时有两个参数,后一个参数一般用引用,为什么呢?看看Add成员函数就可以明。Add函数的作用是向数组添加一个元素。下面是它的定义:int CArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)Add函数使用的参数是模板参数的二个参数,也就是说,这个参数的类型是我们来决定的,可以使用Object或Object&的方式。熟悉C++的朋友都知道,传引用的效率要高一些。如果是传值的话,会在堆栈中再产生一个新的对象,需要花费更多的时间。
下面来分析一下Add函数的代码:
template<class TYPE, class ARG_TYPE>
AFX_INLINE int CArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)
{
  int nIndex = m_nSize;
  SetAtGrow(nIndex, newElement);
  return nIndex;
}
它实际是通过SetAtGrow函数来完成这个功能的,它的作用是设置指定元素的值。下面是SetAtGrow的代码:template<class TYPE, class ARG_TYPE>
void CArray<TYPE, ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement)
{
  if (nIndex >= m_nSize)
    SetSize(nIndex+1, -1);
  m_pData[nIndex] = newElement;
}
SetAtGrow的实现也很简单,如果指定的元素已经存在,就把改变指定元素的值。如果指定的元素不存在,也就是 nIndex>=m_nSize的情况,就调用SetSize来调整数组的大小。
其实,到这里,大家对CArray类的内部实现有了一定的了解,只要看看MSDN的文档,就可以灵活运用了。

上一页  1 2 

Tags:深入 分析 MFC

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接