欢迎来到天天文库
浏览记录
ID:55339549
大小:55.50 KB
页数:5页
时间:2020-05-11
《VC中一个于宏的使用问题.doc》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、VC中一个关于宏的使用问题这儿是个关于宏的问题,我曾用过ATL的串转换宏,包括W2A,开始有些东西我还不太明白。为了使用这些宏,必须在函数的开始处用USES_CONVERSION来初始化某些局部变量。用就用吧,但是看看这个宏的定义,它有类似下面的代码:1.//在atlconv.h文件中2.#defineUSES_CONVERSION3.int _convert;_convert;4.UINT _acp=GetACP();_acp;5.LPCWSTR _lpw;_lpw; 6.LPCSTR _lpa;_lpa为什么它们用“intx;x;”——这种后面跟着变量的声明?很多人都碰到过这个令
2、人困惑的问题,后来发现简单的答案是:禁止编译器的警告信息(warning)。如果单独有一行代码:1.int x;且从来没有使用过x,那么编译器汇报错“unreferencedlocalvariable:x”,意思是未引用过的局部变量x,如果将警告信息的输出调到最大。为了避免讨厌的警告,USES_CONVERSION引用声明的变量。1.int x; //声明2.x; //使用这个变量5在C++之前的时代,程序员有时在C中用函数形参做同样的事情来避免“unreferencedformalparameter”或其它的深奥费解的编译错误。1.void MyFunc(int x, char y)2.{
3、3.x;4.y;5.…6.}当然,现在用下面的代码可以更有效地完成同样的事情:1.//参数x不是用2.void MyFunc(int /*x*/) 3.{4.…5.}也就是说声明参数,但不给它起名,不能这样使用局部变量;必须显式地引用它。这样做不会增加任何指令到代码中。最多可能多增加几个字节到堆栈(为x预留空间)。灵巧的编译器甚至不会操心x从来没有被使用过——虽然好奇心可能想知道:如果编译器够厉害,知道了从没有使用x,为什么要抱怨(编译出错)呢?答案是因为苛刻的程序员(且编程能力与个人的记性有关)使用编译警告提醒自己删除某部分代码时发生变量荒废。这种警告在C时代很有用,你必须在每个函数的顶部
4、声明变量,这就远离了实用它们的代码。现在来看看另一个问题:为什么在开始位置要用USES_CONVERSION?即为什么W2A&Co之类的宏还需要另外的宏声明自己的变量;为什么不直接在W2A中声明这个变量?51.#defineW2A(x)2.int _convert;_convert;3.……etc很明显这样做不行,因为如果你使用W2A两次,得到一个复制的变量。那为什么不把整个宏放进花括弧创建新的范围?1.#defineW2A(x)Q{2.int _convert;_convert;3.……4.}这样解决了命名冲突,但不能进行如下编码:1.DoSomething(W2A(pwstr)
5、);没有办法从代码块返回值,所以不能在函数调用中传递W2A。真笨啊,那么内联函数怎么样?1.inline LPCSTR W2A(LPWSTR w){2.int_convert;3.……4.}这解决了范围问题——任何W2A需要的变量多可以在这个函数中,在自己的范围内声明,不需要另外的宏。它也提供了一种返回值的方式,使你可以在函数调用和赋值中使用W2A(x)。但是这种方法不灵,也是因为W2A的缘故和其它的宏更复杂。不管什么时候进行Unicode转换,都不能就地转换串,必须分配一个临时串容纳被转换的字节。典型地,通过调用new分配一个串:1.int len=MultiByteToWideChar(
6、..., 2.mystr,NULL,0); //或的长度3.LPWSTR p= new WCHAR[nLen]; //分配内存4.MultiByteToWideChar(...,p,len); //转换55.SomeCOMFunction(p); //使用之6.delete []p; //销毁这段代码不仅令人讨厌,而且还没有效率;必须调用MultiByteToWideChar两次(一次是计算长度,一次是实际的转换),你得从堆中分配p,这样很慢。通过分配2*len个字节解决第一个问题,这里长度len是ASCII串的长度——但第二个问题怎么办?如果看看A2W是如何展开的,请看:1.//简化版2.
7、#defineA2W(s)3._len=2*strlen(s);4.AfxA2WHelper((LPWSTR)alloca(_len);AfxA2Whelper是一个调用MultiByteToWideChar的辅助函数。A2W使用2*len巧妙地避免了两次调用MultiByteToWideChar。但A2W及其它转换宏真正聪明的地方是不调用new操作分配临时串,而是调用alloca——在栈中分配字节,而不是
此文档下载收益归作者所有