作者:饭中淹 来源:C++博客   酷勤网收集 2008-04-11

摘要
  在部分场合,我们可能会希望把一个指针替换为一个string对象,或者把一个string对象,替换为一个指针,而且我们对结构体的大小很敏感,union也行不通。如果我们放一个string的指针,那么我们就需要new一个string对象出来,然后string内部再去new一个char[]的数组。

我一般编程的时候,喜欢用我自己设计的string类,最近在设计结构体的时候,我想到了一个适合结构体使用的string类的设计方法,不过可能我比较孤陋寡闻,这个方法以前就有人实现过,不过还是记录下来。

一般来说,string,至少需要保存一个char*的指针和一个int的长度,复杂点的,可能还需要更多的成员。

这样的话,我们需要至少8个字节来保存这个string对象(32bit下)。

在部分场合,我们可能会希望把一个指针替换为一个string对象,或者把一个string对象,替换为一个指针,而且我们对结构体的大小很敏感,union也行不通。如果我们放一个string的指针,那么我们就需要new一个string对象出来,然后string内部再去new一个char[]的数组。

为此,我想了一个办法来解决这个问题。我在string内部引入一个context的东西,它保存了所有string的成员变量,然后结尾是字符串数组,形似下面这个结构:

1    typedef struct tagStringContext
2    {
3        int nMaxLength;
4        int nLength;
5        char szBuf[1];
6    }
t_StringContext;
7

每次分配内存的时候,把这个结构放在头部,然后分配 长度+sizeof(int)*2的内存,用来创建一个字符串。

m_pContext = (t_StringContext*)alloc( sizeof(int)*2 + nMaxLength );
m_pContext
->nMaxLength = nMaxLength;
m_pContext
->nLength = nLength;
memcpy( (LPVOID)m_pContext
->szBuf, (LPVOID)pszString, nLength + 1 ); // with zero tail


这样,string类只要有m_pContext这一个成员就行了,而这个成员,就是t_StringContext*类型的,它是一个指针。这就意味着,它可以从任意的可以容纳一个指针的位置构造出来。
如果你在考虑如果m_pContext为null怎么办的话,那当然是string返回空字符串和0 length了。

这种方法只要做一次内存分配,就可以在一个指针位置构造出一个string对象来。

不过,一定要保证string类里面没有虚函数,因为它会在类对象的前头加上一些信息(虚表指针之类的东西)。

另外,因为我对其他编译器不是很熟悉,我只在ms vc8.0,7.0,6.0自带的编译器上测试过。而在其他编译器上,这个方法可能失效。

来自:http://www.cppblog.com/johndragon/archive/2008/04/11/46817.html

分类: 编程语言 C/C++编程语言 修炼之道



关于酷勤 | 联系方式 | 免责声明 | 友情链接