指针 = 效率?

在C++语言中,我们是应该存储对象本身还是对象的指针呢?储存指针就一定比对象本身节约空间和高效吗?最近在做一个程序,程序要求访问大量的字符串,在程序中每个相同的字符串只有一个唯一的副本。我构造了一个类KCStringManager,其中的方法LPCTSTR GetString(LPCTSTR lpszName)用于返回储存在Hash表中的字符串指针,这个字符串等于lpszName,由此保证每个字符串指针的唯一性。这样带来的好处是:首先节省了空间;其次,后期字符串的比较工作非常高效,只需要比较它们的指针是否指向同一个地址。这正是很多编译器所使用的方法。

另外,我还构造了一个KSymbol类,其中包含数据成员LPCTSTR m_lpszName。我一直考虑的问题是:是否可以把LPCTSTR指针封装成类,这样带来的开销是什么。考虑下面的字符串类:

class KString
{
public:
    KString(LPCTSTR lpszName);
    KString(KString& s);
    BOOL operator == (KString& s) const;
    KString& operator = (KString& s);
    ....
private:
    LPCTSTR m_lpszName;
};

首先来分析它的空间开销:类中只有一个数据成员LPCTSTR,没有虚函数,因而sizeof(KString) == sizeof(LPCTSTR)。其次分析它的拷贝开销:

KString& KString::operator = (KString& s)
{
    m_lpszName = s.m_lpszName;
}

只有一步操作,和LPCTSTR的直接复制操作相同。由此我们可得出结论:把LPCTSTR封装成类成员并没有引入额外的时间或空间开销。

另外一个需要考虑的问题:应该在KSymbol中保存KString类本身还是指向KString的指针?先考虑指针问题。KString对象指针所占的空间为指针大小,即sizeof(void*)。但对于每个KSymbol实例,我们必须额外的调用new为KString分配空间,这样一来需要额外的sizeof(KString)空间,而且new操作也是颇费时的。接下来考虑保存对象本身的问题。其空间开销为sizeof(KString) == sizeof(LPCTSTR) == sizeof(void*) == sizeof(KString*),虽然和保存指针所耗的空间一致,但是却节省了在堆上分配的空间以及new操作带来的开销。另外,如上所述,KString的复制开销等于直接对LPCTSTR进行复制的开销。

由上面的讨论,可以得出的一个结论是:在KSymbol保存KString对象和保存LPCTSTR对象的开销是相同的。但是,适用前者明显对以后的维护带来了方便。另外,保存KString*的开销则大于直接保存KString对象的开销。也就是说,我们遇到了一个直接存储对象本身比存储对象指针更高效的场合。

posted @ 2006-03-21 09:37  Goncely  阅读(194)  评论(0编辑  收藏  举报