设为首页 加入收藏

TOP

代码高处走 从VC6到VC9移植代码问题说明(四)
2014-11-23 20:26:41 来源: 作者: 【 】 浏览:264
Tags:代码 高处 VC6 VC9 移植 问题 说明
),所以以前的代码通常是这样使用的:

  TCHAR *cp = _tcschr( pszPath, _T('\\') );

  //使用*cp,可以通过cp指针修改pszPath的内容

  这其实是一个“ 漏洞”,因为如果pszPath是const char(TCHAR) *字符串,那么就表示它不希望修改字符串的内容,但是调用strchr(_tcschr)函数后就可以通过cp指针修改其内容了,这岂不荒谬?所以在新版本的CRT库中,这几个函数的返回值都改成了const char *,这就会导致上面的代码产生编译错误。建议的修改方式是改成如下方式:

  const TCHAR *cp = _tcschr( pszPath, _T('\\') );

  //不能再通过cp指针修改pszPath的内容

  但是这样修改可能对代码的影响比较大,比如下面的代码:

  TCHAR buf[256]; //局部缓冲区

  ......

  TCHAR *cp = _tcschr( buf, _T('\\') );

  //作为局部缓冲区(非const),希望通过cp修改buf的内容

  这种情况怎么办呢?对了,C++还有个const_cast操作符,这时就可以排上用场了:

  TCHAR *cp = const_char(_tcschr( buf, _T('\\') ));

  不过上面的方法要慎用,除非确定buf是非const的,否则最好老老实实地修改代码。

  十一、类成员函数指针做为函数参数的“C3867”错误

  考察下面的代码,CWzWindowsHook类的构造函数使用一个该类的成员函数指针,这样构造对象时可以选择消息过滤的handler,可以是MouseMsgFilter,也可以是KeyboardMsgFilter:(#add 这个类的设计值得学习)

  typedef BOOL (CWzWindowsHook::*FILTERPROC)(WPARAM wParam, LPARAM lParam);

  // A hook used in customization sheet to filter keyboard/mouse events

  class CWzWindowsHook

  {

  private:

  FILTERPROC m_pFilter;

  BOOL MouseMsgFilter(WPARAM wParam, LPARAM lParam);

  BOOL KeyboardMsgFilter(WPARAM wParam, LPARAM lParam);

  public:

  CWzWindowsHook(FILTERPROC pFilter) : m_pFilter(pFilter)

  旧的遗留代码存在这样的用法:

  CWzWindowsHook mouseHooker(CWzWindowsHook::MouseMsgFilter);

  在VC6的编译器下编译可能没有问题,但是在VC9的编译器下编译会有如下报错:

  f:\project\.....\WzWindowsHook.cpp(272) : error C3867: 'CWzWindowsHook::MouseMsgFilter': function call missing argument list; use '&CWzWindowsHook::MouseMsgFilter' to create a pointer to member

  虽然C++从C继承来了函数名即是函数地址的语法规则,但是根据C++的标准,类成员函数的指针仍然需要一个取地址符“&”。解决方法很简单,按照提示改成如下代码即可:

  CWzWindowsHook mouseHooker(&CWzWindowsHook::MouseMsgFilter);

  十二、wchar_t *类型与USHORT *的转换错误

  VC6的编译器不支持wchar_t数据类型,wchar_t实际上被定义成unsigned short,VC9的编译器已经支持wchar_t为内置数据类型,但是由一个编译选项控制,这个选项默认是打开的,也就是将wchar_t作为编译器的内置数据类型。但是OLECHAR和WCHAR的定义仍然是unsigned short,在VC6的编译环境中,两者的指针都是USHORT *,相互赋值和做为函数参数传递没有问题,但是如果wchar_t作为编译器的内置数据类型,那就意味着wchar_t *与OLECHAR *或WCHAR *是两种不同类型的指针,相互赋值就会报编译错误,下面的信息就是一个典型的错误输出:

  f:\project\.....\shellpidl.cpp(290) : error C2664: 'MultiByteToWideChar' : cannot convert parameter 5 from 'USHORT *' to 'LPWSTR'

  Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

  解决的方法就是使用C++的reinterpret_cast操作符或使用C-style强制转换,当然也可以在项目属性设置中关闭前面提到的那个选项(这个偶美试过,不知道会不会有其它问题)。

附:

十三、模板特化(Template specialization)
模板的特殊化是当模板中的pattern有确定的类型时,模板有一个具体的实现。例如假设我们的类模板pair 包含一个取模计算(module operation)的函数,而我们希望这个函数只有当对象中存储的数据为整型(int)的时候才能工作,其他时候,我们需要这个函数总是返回0。这可以通过下面的代码来实现:

template

class Pair {

T value1, value2;

public:

Pair (T first, T second){

value1=first;

value2=second;

}

T module () {return 0;}

};

template <>

class Pair {

int value1, value2;

public:

Pair (int first, int second){

value1=first;

value2=second;

}

int module ();

};

//在模板特例化中,NET的特性

template<> int Pair::module() {

return value1%value2;

}

这里要注意,在.NET中template<>是不需要的,否则会发生

Compiler Error C2910

Error Message

'function' : cannot be explicitly specialized错误,

见:http://msdn.microsoft.com/en-us/library/cx7k7hcf(VS.80). aspx



十四、关于DX8SDK使用中link
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC+ADO 连接ACCESS和SQL SERVER的.. 下一篇VC++ 6.0点打开按钮出现 “Micros..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: