在词法分析的时候,以下面的代码为例。
class String
{
public :
typedef unsigned char byte_t;
typedef unsigned long size_t;
public :
String()
{
}
};
这里面,每一个Token的长度往往不超过7,所以这个String在处理string length的长度小于7的字符串的时候,不需要在堆上分配内存。
而且整个类的sizeof(String)只有8,远远小于VC实现的std::string的sizeof( std::string )==28。
缺点是,很多关于字符串的操作会判断一个标志位,影响了速度,但是从词法分析的角度考虑,String类的整体表现会很好。
聚合了这个结构。
union string_t
{
struct SP
{
byte_t * ptr;
unsigned short len;
byte_t flag;
byte_t unused;
} s2;
struct SA
{
byte_t arr[ 8 ];
} s1;
} s;
整个代码是这样的。
#ifndef __STRING_HPP__
#define __STRING_HPP__
#include " Alloc.hpp "
#define CRITICAL 0x07
class String
{
public :
typedef unsigned char byte_t;
typedef unsigned long size_t;
public :
String()
{
}
String( const char * str)
{
size_t len = strlen(str);
if (len < CRITICAL)
{
_construct1(( const byte_t * )str, len);
}
else
{
_construct2(( const byte_t * )str, len);
}
}
String(String const & _right)
{
size_t len = _right.length();
if (len < CRITICAL)
{
_construct1(( const byte_t * )_right.bytes(), len);
}
else
{
_construct2(( const byte_t * )_right.bytes(), len);
}
}
String( const char * str, size_t offset, size_t len)
{
size_t leave = strlen(str + offset);
if (leave < CRITICAL)
{
_construct1(( const byte_t * )str + offset, (len < leave) ? len : leave);
}
else
{
_construct2(( const byte_t * )str + offset, (len < leave) ? len : leave);
}
}
size_t length() const
{
return (s.SP::flag) ? (size_t)s.SP::len : (size_t)s.SA::arr[ 7 ];
}
const byte_t * bytes() const
{
return (s.SP::flag) ? ( const byte_t * )s.SP::ptr : ( const byte_t * )s.SA::arr;
}
String replace(String const & str1, String const & str2)
{
return String();
}
String substring(size_t offset, size_t count)
{
return String(( const char * )bytes(), offset, count);
}
private :
void _construct1( const byte_t * ptr, size_t len)
{
strcpy(( char * )s.SA::arr, ( char * )ptr);
s.SA::arr[ 6 ] = 0 ;
s.SA::arr[ 7 ] = (byte_t)len;
}
void _construct2( const byte_t * ptr, size_t len)
{
byte_t * p = Alloc < byte_t > ::alloc(len);
strcpy(( char * )p, ( const char * )ptr);
s.SP::ptr = p;
s.SP::len = (unsigned short )len;
s.SP::flag = (byte_t) 0xff ;
s.SP::unused = (byte_t) 0x00 ;
}
private :
union string_t
{
struct SP
{
byte_t * ptr;
unsigned short len;
byte_t flag;
byte_t unused;
} s2;
struct SA
{
byte_t arr[ 8 ];
} s1;
} s;
};
#endif
测试一下:
int s = sizeof (String);
String s1( " Hello " );
String s2( " Hello world " );
String s3 = s2;
char * p1 = ( char * )s1.bytes();
char * p2 = ( char * )s2.bytes();
int l1 = s1.length();
int l2 = s2.length();
int l3 = s3.length();
String s4 = s2.substring( 6 , 5 );
int l4 = s4.length();
String s5 = s2.substring( 6 , 6 );
int l5 = s4.length();
String s6 = s1.substring( 0 , 3 );
int l6 = s6.length();
转载于:https://www.cnblogs.com/healerkx/articles/1338551.html