好处是不必为它想一个名字。使用_L会创建临时TPtrC类型的临时开销。
补充:
文字描述符(Literal Descriptors)
在这里面定义了一些宏和一些类,这些类的对象是常量描述符,它们被编译器创建在只读内存上。
这里面又很多比_L高效的宏,但是为了系统兼容性考虑,我们仍然保留了_L宏。
一、系统定义的描述符:
KNullDesC16
_LIT16(KNullDesC16,"");
表示空或者无文本的16位格式描述符。
KNullDesC8
_LIT8(KNullDesC8,"");
表示空或者无文本的8位格式描述符。
KNullDesC
_LIT(KNullDesC,"");
表示空或者无文本的描述符。在non-Unicode编码系统中,表示8位格式描述符;在Unicode编码系统中,表示16格式描述符。
二、宏
(1)
_L8
#define _L8(a) (TPtrC8((const TText8 *)(a)))
不管系统什么编码格式,该宏创建一个8位格式的常量文本。
_L16
#define _L16(a) (TPtrC16((const TText16 *)L ## a))
不管系统什么编码格式,该宏创建一个16位格式的常量文本。
_L
#if defined(_UNICODE)
typedef TText16 TText;
#define _L(a) (TPtrC((const TText *)L ## a))
...
#else
typedef TText8 TText;
#define _L(a) (TPtrC((const TText *)(a)))
...
#endif
根据系统具体编码格式,动态确定创建一个8位或16位格式的常量文本。
(2)
_LIT8
#define _LIT8(name,s) const static TLitC8<sizeof(s)> name={sizeof(s)-1,s}
使用指定的名字和文本内容创建一个TLitC8<TInt>类型的常量描述符。
_LIT16
#define _LIT16(name,s) const static TLitC16<sizeof(L##s)/2> name={sizeof(L##s)/2-1,L##s}
使用指定的名字和文本内容创建一个TLitC16<TInt>类型的常量描述符。
_LIT
#if defined(_UNICODE)
#define _LIT(name,s) const static TLitC<sizeof(L##s)/2> name={sizeof(L##s)/2-1,L##s}
#else
#define _LIT(name,s) const static TLitC<sizeof(s)> name={sizeof(s)-1,s}
#endif
对于non-Unicode编码系统,创建一个TLitC8<TInt>类型的常量描述符;对于Unicode编码系统,创建一个个TLitC16<TInt>类型的常量描述符。
(3)
_S8
#define _S8(a) ((const TText8 *)a)
创建一个8位的常量串。
_S16
#define _S16(a) ((const TText16 *)L ## a)
创建一个16位的常量串。
_S
#if defined(_UNICODE)
typedef TText16 TText;
...
#define _S(a) ((const TText *)L ## a)
#else
typedef TText8 TText;
...
#define _S(a) ((const TText *)a)
#endif
根据不同的系统,创建一8位或16位的常量串。
通过观察这三种宏的具体定义形式,发现它们的不同点:
_L产生的对象没有名字,它的类型是TPtrC
_S产生的对象也没有名字,它的类型是const TText *
_LIT产生的对象有名字,它的类型是const static TLitC
相同点:
对象都是常量不可变的。
它们都被创建在只读内存里。
三、类
(1)
Class TLitC8
对象表示一个8位格式的常量描述符,没有构造函数,使用宏_LIT8创建对象。
Class TLitC16
对象表示一个16位格式的常量描述符,没有构造函数,使用宏_LIT16创建对象。
Class TLitC
对象创建一个8位或16位格式的常量描述符,没有构造函数,使用宏_L创建对象。
这三个类均定义了4个操作符重载"()",这4个重载操作符的返回值不同。
(2)
Typedef __TRefDesC8
typedef TRefByValue<const TDesC8> __TRefDesC8;
表示一个指向TDesC8描述符的引用,通过TLitC8::__TRefDesC8()创建。
Typedef __TRefDesC16
typedef TRefByValue<const TDesC16> __TRefDesC16;
表示一个指向TDesC16描述符的引用,通过TLitC16::__TRefDesC16()创建。
Typedef __TRefDesC
typedef TRefByValue<const TDesC> __TRefDesC;
通过TLitC::__TRefDesC()创建。
Class TRefByValue
TRefByValue<class T> //模板类
四、使用宏_LIT
_LIT(KSomeBuildIndependentLitText,"qwerty"); //create literal
iEikonEnv->InfoMsg(KSomeBuildIndependentLitText);
上面的代码相当于:
const static TLitC<7> KSomeBuildIndependentLitText;
iEikonEnv->InfoMsg(KSomeBuildIndependentLitText);
上面的代码可以如果使用宏_L的话,可以这样修改:
iEikonEnv->InfoMsg(_L("qwerty"));
同样的,对于16位格式描述符和8位格式描述符,可以如下定义:
_LIT16(KSomeLIT16Text,"qwerty");
相当于:const static TLitC16<7> KSomeLIT16Text;
_LIT8(KSomeLIT8Text,"qwerty");
相当于:const static TLitC8<7> KSomeLIT8Text;
五、使用类TLitC的重载操作符
一共有4个重载操作符,返回类型分别是:
(1)一个TRefByValue<class T>类型的引用
示例程序
...
TBuf<256> x;
...
_LIT(KTxtFormat,"There are %d cm in a metre");
x.Format(KTxtFormat,100); //编译器自动调用重载操作符
...
(2)指向常量描述符的常量引用
...
_LIT(KSomeData,"Some data");
...
TPtrC x(KSomeData);
(3)指向常量描述符的指针
class CX...
{
void Foo(const TDesC* aDesC);
};
...
_LIT(KLiteral,"some text");
...
CX* anx;
...
anx->Foo(&KLiteral);
...
(4)一个常量描述符的引用
...
_LIT(KKeywordSelect,"select");
if (KKeywordSelect().CompareF(token)<0)
...